de.wpsverlinden.otrsspy.OtrsSpy.java Source code

Java tutorial

Introduction

Here is the source code for de.wpsverlinden.otrsspy.OtrsSpy.java

Source

/*
 * OtrsSpy - A simple OTRS queue extractor
 * Copyright (C) 2014 Oliver Verlinden (http://wps-verlinden.de)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package de.wpsverlinden.otrsspy;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

public class OtrsSpy {

    private final String QUEUE_NAME_PATTERN = "<div class=\"OverviewBox ARIARoleMain Small\"><h1>(.+?)</h1>";
    private final String LOGOUT_TOKEN_PATTERN = "Action=Logout;ChallengeToken=(.+?);\"";
    static final Logger logger = Logger.getLogger(OtrsSpy.class);
    private String[] args;
    private String user;
    private String password;
    private String host;
    private String lang;
    private String session;
    private String logoutToken;
    private List<String> queues = new LinkedList<>();

    private static class ExtractException extends Exception {

        public ExtractException(String msg) {
            super(msg);
        }
    }

    public static void main(String[] args) {
        OtrsSpy app = new OtrsSpy(args);
        app.start();
    }

    private OtrsSpy(String[] args) {
        this.args = args;
    }

    private void start() {
        PropertyConfigurator.configure(getClass().getResource("/log4j.properties"));
        try {
            init(args);
            login();
            extractQueues();
            logout();
            printQueues();
        } catch (ExtractException ex) {
            logger.warn(ex.getMessage());
        } catch (MalformedURLException ex) {
            logger.error(ex);
        } catch (IOException ex) {
            logger.error(ex);
        }
    }

    private void init(String[] args) {
        Options options = new Options();
        options.addOption(OptionBuilder.withArgName("host").isRequired().hasArg()
                .withDescription("host running OTRS (e.g. \"http://company.intranet/otrs/\"").create("h"));
        options.addOption(OptionBuilder.withArgName("user").isRequired().hasArg()
                .withDescription("user of any valid oats agent").create("u"));
        options.addOption(OptionBuilder.withArgName("password").isRequired().hasArg()
                .withDescription("password of any valid oats agent").create("p"));
        options.addOption(OptionBuilder.withArgName("language").hasArg()
                .withDescription("language code of the OTRS instance (default: de)").create("l"));
        try {
            CommandLineParser parser = new PosixParser();
            CommandLine cmd = parser.parse(options, args);

            host = cmd.getOptionValue("h");
            user = cmd.getOptionValue("u");
            password = cmd.getOptionValue("p");
            lang = cmd.hasOption("l") ? cmd.getOptionValue("l") : "de";

            if (!host.endsWith("/")) {
                host = host.concat("/");
            }

        } catch (ParseException pe) {
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("java -jar otrsspy", options, true);
            System.exit(0);
        }

    }

    private void login() throws MalformedURLException, IOException, ExtractException {
        logger.info("Login...");
        HttpURLConnection conn = (HttpURLConnection) (new URL(host + "index.pl")).openConnection();
        conn.setRequestMethod("POST");
        conn.setInstanceFollowRedirects(false);
        conn.setDoOutput(true);
        try (DataOutputStream wr = new DataOutputStream(conn.getOutputStream())) {
            wr.writeBytes("Action=Login&RequestedURL=&Lang=" + lang + "&TimeOffset=-120&User=" + user + "&Password="
                    + password);
            wr.flush();
        }
        session = extractSession(conn);
    }

    private String extractSession(HttpURLConnection conn) throws ExtractException {
        String s;
        logger.info("Extracting session token... ");
        String cookie = conn.getHeaderField("Set-Cookie");
        if (cookie == null || cookie.isEmpty()) {
            throw new ExtractException("Could not find session token. Please check user and password.");
        }
        Pattern pattern = Pattern.compile("Session=([a-z0-9]*);");
        Matcher matcher = pattern.matcher(cookie);
        if (matcher.find()) {
            s = matcher.group(1);
            logger.debug("Extract session token " + s);
        } else {
            throw new ExtractException("Could not find session token. Please check user and password.");
        }
        return s;
    }

    private void extractQueues() throws MalformedURLException, IOException {
        logger.info("Extracting queues...");

        String myQueuesLabel = "";
        String lastQueueName = "x";
        int i = 0;
        do {
            String content = probeQueue(i);
            if (logoutToken == null) {
                logger.info("Extracting logout token... ");
                logoutToken = extractLogoutToken(content);
            }

            String name = extractName(content);
            if (name != null) {
                if (myQueuesLabel.isEmpty()) {
                    myQueuesLabel = name;
                } else {
                    queues.add(name);
                    lastQueueName = name;
                }
                logger.debug("Probing queue " + i + " found");
            } else {
                logger.debug("Probing queue " + i + " not found");
            }
            i++;
        } while (!lastQueueName.equals(myQueuesLabel));

        //Remove last element 
        queues.remove(queues.size() - 1);
    }

    private String probeQueue(int i) throws MalformedURLException, IOException {
        URL url = new URL(host + "index.pl?Action=AgentTicketQueue;QueueID=" + i + ";View=");
        logger.debug("Sending probe request " + url.toString());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setInstanceFollowRedirects(false);
        conn.setRequestProperty("Cookie", "Session=" + session);
        logger.debug("Receiving logout reply " + conn.getResponseCode());
        return convertToString(conn.getInputStream());
    }

    private String convertToString(InputStream inputStream) throws IOException {
        BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String line;

        while ((line = rd.readLine()) != null) {
            sb.append(line.trim());
        }
        return sb.toString();
    }

    private String extractName(String content) {
        Pattern pattern = Pattern.compile(QUEUE_NAME_PATTERN);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            String name = matcher.group(1);
            int separator = name.indexOf(":");
            logger.debug("Extract queue name " + name.substring(separator + 2));
            return name.substring(separator + 2);
        } else {
            return null;
        }
    }

    private String extractLogoutToken(String content) {
        Pattern pattern = Pattern.compile(LOGOUT_TOKEN_PATTERN);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            logger.debug("Extract logout token " + matcher.group(1));
            return matcher.group(1);
        } else {
            return null;
        }
    }

    private void logout() throws MalformedURLException, IOException {
        URL url = new URL(host + "index.pl?Action=Logout;ChallengeToken=" + logoutToken + ";");
        logger.info("Logout... ");
        logger.debug("Sending logout request " + url.toString());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setInstanceFollowRedirects(false);
        conn.setRequestProperty("Cookie", "Session=" + session);
        logger.debug("Receiving logout reply " + conn.getResponseCode());
    }

    private void printQueues() {
        System.out.println("\nSucessfully extracted " + queues.size() + " queues:");
        for (String name : queues) {
            System.out.println(name);
        }
    }
}