Search in sources :

Example 1 with CredentialInvalidException

use of me.vertretungsplan.exception.CredentialInvalidException in project substitution-schedule-parser by vertretungsplanme.

the class LoginHandler method handleLogin.

private String handleLogin(Executor executor, CookieStore cookieStore, boolean needsResponse) throws JSONException, IOException, CredentialInvalidException {
    if (auth == null)
        return null;
    if (!(auth instanceof UserPasswordCredential || auth instanceof PasswordCredential)) {
        throw new IllegalArgumentException("Wrong authentication type");
    }
    String login;
    String password;
    if (auth instanceof UserPasswordCredential) {
        login = ((UserPasswordCredential) auth).getUsername();
        password = ((UserPasswordCredential) auth).getPassword();
    } else {
        login = null;
        password = ((PasswordCredential) auth).getPassword();
    }
    JSONObject data = scheduleData.getData();
    JSONObject loginConfig = data.getJSONObject(LOGIN_CONFIG);
    String type = loginConfig.optString(PARAM_TYPE, "post");
    switch(type) {
        case "post":
            List<Cookie> cookieList = cookieProvider != null ? cookieProvider.getCookies(auth) : null;
            String checkUrl = loginConfig.optString(PARAM_CHECK_URL, null);
            String checkText = loginConfig.optString(PARAM_CHECK_TEXT, null);
            if (cookieList != null && !needsResponse && !(checkUrl == null && checkText != null)) {
                for (Cookie cookie : cookieList) cookieStore.addCookie(cookie);
                if (checkUrl != null && checkText != null) {
                    try {
                        String response = executor.execute(Request.Get(checkUrl)).returnContent().asString();
                        if (!response.contains(checkText)) {
                            return null;
                        }
                    } catch (HttpResponseException e) {
                        return null;
                    }
                } else {
                    return null;
                }
            }
            executor.clearCookies();
            Document preDoc = null;
            if (loginConfig.has(PARAM_PRE_URL)) {
                String preUrl = loginConfig.getString(PARAM_PRE_URL);
                String preHtml = executor.execute(Request.Get(preUrl)).returnContent().asString();
                preDoc = Jsoup.parse(preHtml);
            }
            String postUrl = loginConfig.getString(PARAM_URL);
            JSONObject loginData = loginConfig.getJSONObject(PARAM_DATA);
            List<NameValuePair> nvps = new ArrayList<>();
            String typo3Challenge = null;
            BigInteger typo3RsaN = null;
            BigInteger typo3RsaE = null;
            if (loginData.has("_hiddeninputs") && preDoc != null) {
                for (Element hidden : preDoc.select(loginData.getString("_hiddeninputs") + " input[type=hidden]")) {
                    if (loginData.has(hidden.attr("name")))
                        continue;
                    nvps.add(new BasicNameValuePair(hidden.attr("name"), hidden.attr("value")));
                    if (hidden.attr("name").equals("challenge")) {
                        typo3Challenge = hidden.attr("value");
                    } else if (hidden.attr("name").equals("n") && hidden.attr("id").equals("rsa_n")) {
                        typo3RsaN = new BigInteger(hidden.attr("value"), 16);
                    } else if (hidden.attr("name").equals("e") && hidden.attr("id").equals("rsa_e")) {
                        typo3RsaE = new BigInteger(hidden.attr("value"), 16);
                    }
                }
            }
            for (String name : JSONObject.getNames(loginData)) {
                String value = loginData.getString(name);
                if (name.equals("_hiddeninputs"))
                    continue;
                switch(value) {
                    case "_login":
                        value = login;
                        break;
                    case "_password":
                        value = password;
                        break;
                    case "_password_md5":
                        value = DigestUtils.md5Hex(password);
                        break;
                    case "_password_md5_typo3":
                        value = DigestUtils.md5Hex(login + ":" + DigestUtils.md5Hex(password) + ":" + typo3Challenge);
                        break;
                    case "_password_rsa_typo3":
                        try {
                            final Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                            if (typo3RsaE == null && typo3RsaN == null) {
                                String key = executor.execute(Request.Get(new URL(new URL(postUrl), "/index.php?eID=FrontendLoginRsaPublicKey").toString())).returnContent().asString();
                                typo3RsaN = new BigInteger(key.split(":")[0], 16);
                                typo3RsaE = new BigInteger(key.split(":")[1], 16);
                            }
                            cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(typo3RsaN, typo3RsaE)));
                            byte[] result = cipher.doFinal(password.getBytes());
                            value = "rsa:" + new Base64().encodeAsString(result);
                        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) {
                            e.printStackTrace();
                        }
                        break;
                }
                nvps.add(new BasicNameValuePair(name, value));
            }
            Request request = Request.Post(postUrl);
            if (loginConfig.optBoolean("form-data", false)) {
                MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                for (NameValuePair nvp : nvps) {
                    builder.addTextBody(nvp.getName(), nvp.getValue());
                }
                request.body(builder.build());
            } else {
                request.bodyForm(nvps, Charset.forName("UTF-8"));
            }
            String html = executor.execute(request).returnContent().asString();
            if (cookieProvider != null)
                cookieProvider.saveCookies(auth, cookieStore.getCookies());
            if (checkUrl != null && checkText != null) {
                try {
                    String response = executor.execute(Request.Get(checkUrl)).returnContent().asString();
                    if (response.contains(checkText))
                        throw new CredentialInvalidException();
                } catch (HttpResponseException e) {
                    throw new CredentialInvalidException();
                }
            } else if (checkText != null) {
                if (html.contains(checkText))
                    throw new CredentialInvalidException();
            }
            return html;
        case "basic":
            if (login == null)
                throw new IOException("wrong auth type");
            executor.auth(login, password);
            if (loginConfig.has(PARAM_URL)) {
                String url = loginConfig.getString(PARAM_URL);
                if (executor.execute(Request.Get(url)).returnResponse().getStatusLine().getStatusCode() != 200) {
                    throw new CredentialInvalidException();
                }
            }
            break;
        case "ntlm":
            if (login == null)
                throw new IOException("wrong auth type");
            executor.auth(login, password, null, null);
            if (loginConfig.has(PARAM_URL)) {
                String url = loginConfig.getString(PARAM_URL);
                if (executor.execute(Request.Get(url)).returnResponse().getStatusLine().getStatusCode() != 200) {
                    throw new CredentialInvalidException();
                }
            }
            break;
        case "fixed":
            String loginFixed = loginConfig.optString(PARAM_LOGIN, null);
            String passwordFixed = loginConfig.getString(PARAM_PASSWORD);
            if (!Objects.equals(loginFixed, login) || !Objects.equals(passwordFixed, password)) {
                throw new CredentialInvalidException();
            }
            break;
    }
    return null;
}
Also used : Base64(org.apache.commons.codec.binary.Base64) MultipartEntityBuilder(org.apache.http.entity.mime.MultipartEntityBuilder) Element(org.jsoup.nodes.Element) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) ArrayList(java.util.ArrayList) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) HttpResponseException(org.apache.http.client.HttpResponseException) RSAPublicKeySpec(java.security.spec.RSAPublicKeySpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) Document(org.jsoup.nodes.Document) URL(java.net.URL) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) Cookie(org.apache.http.cookie.Cookie) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) Request(org.apache.http.client.fluent.Request) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) JSONObject(org.json.JSONObject) BigInteger(java.math.BigInteger) Cipher(javax.crypto.Cipher)

Example 2 with CredentialInvalidException

use of me.vertretungsplan.exception.CredentialInvalidException in project substitution-schedule-parser by vertretungsplanme.

the class ESchoolParser method getSubstitutionSchedule.

@Override
public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONException, CredentialInvalidException {
    if (!(scheduleData.getAuthenticationData() instanceof NoAuthenticationData) && (credential == null || !(credential instanceof PasswordCredential) || ((PasswordCredential) credential).getPassword() == null || ((PasswordCredential) credential).getPassword().isEmpty())) {
        throw new IOException("no login");
    }
    List<NameValuePair> nvps = new ArrayList<>();
    nvps.add(new BasicNameValuePair("wp", scheduleData.getData().getString(PARAM_ID)));
    nvps.add(new BasicNameValuePair("go", "vplan"));
    nvps.add(new BasicNameValuePair("content", "x14"));
    nvps.add(new BasicNameValuePair("sortby", "S"));
    String url = BASE_URL + "?" + URLEncodedUtils.format(nvps, "UTF-8");
    Document doc = Jsoup.parse(httpGet(url, ENCODING));
    if (doc.select("form[name=loginform]").size() > 0 && scheduleData.getAuthenticationData() instanceof PasswordAuthenticationData) {
        // Login required
        List<NameValuePair> formParams = new ArrayList<>();
        formParams.add(new BasicNameValuePair("password", ((PasswordCredential) credential).getPassword()));
        formParams.add(new BasicNameValuePair("login", ""));
        doc = Jsoup.parse(httpPost(url, ENCODING, formParams));
        if (doc.select("font[color=red]").text().contains("fehlgeschlagen")) {
            throw new CredentialInvalidException();
        }
    }
    SubstitutionSchedule schedule = parseESchoolSchedule(doc);
    return schedule;
}
Also used : BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) NoAuthenticationData(me.vertretungsplan.objects.authentication.NoAuthenticationData) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) SubstitutionSchedule(me.vertretungsplan.objects.SubstitutionSchedule) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) ArrayList(java.util.ArrayList) PasswordAuthenticationData(me.vertretungsplan.objects.authentication.PasswordAuthenticationData) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) IOException(java.io.IOException) Document(org.jsoup.nodes.Document)

Example 3 with CredentialInvalidException

use of me.vertretungsplan.exception.CredentialInvalidException in project substitution-schedule-parser by vertretungsplanme.

the class UntisInfoParser method getSubstitutionSchedule.

@Override
public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONException, CredentialInvalidException {
    new LoginHandler(scheduleData, credential, cookieProvider).handleLogin(executor, cookieStore);
    Document navbarDoc = Jsoup.parse(getNavbarDoc().replace("&nbsp;", ""));
    Element select = navbarDoc.select("select[name=week]").first();
    SubstitutionSchedule v = SubstitutionSchedule.fromData(scheduleData);
    String info = navbarDoc.select(".description").text();
    String lastChange;
    try {
        lastChange = info.substring(info.indexOf("Stand:") + "Stand:".length()).trim();
    } catch (Exception e) {
        try {
            String infoHtml = httpGet(baseUrl + "/frames/title.htm", data.optString(PARAM_ENCODING, null));
            Document infoDoc = Jsoup.parse(infoHtml);
            String info2 = infoDoc.select(".description").text();
            lastChange = info2.substring(info2.indexOf("Stand:") + "Stand:".length()).trim();
        } catch (Exception e1) {
            lastChange = "";
        }
    }
    List<String> allClasses = new ArrayList<>();
    try {
        allClasses = getAllClasses();
    } catch (IOException e) {
        // we only really need this for teacher schedules
        if (!getLetter(data).equals("v")) {
            throw e;
        }
    }
    int successfulWeeks = 0;
    HttpResponseException lastException = null;
    for (Element option : select.children()) {
        String week = option.attr("value");
        String weekName = option.text();
        if (data.optBoolean(PARAM_SINGLE_CLASSES, // backwards compatibility
        data.optBoolean("single_classes", false)) || data.optString(PARAM_SCHEDULE_TYPE, "substitution").equals("timetable")) {
            int classNumber = 1;
            List<String> classesToSelect;
            if (getLetter(data).equals("v")) {
                classesToSelect = parseTeachers(getNavbarDoc(), data);
            } else {
                classesToSelect = parseClasses(getNavbarDoc(), data);
            }
            for (String klasse : classesToSelect) {
                String url = getScheduleUrl(week, classNumber, data);
                try {
                    parsePage(v, lastChange, klasse, url, weekName, allClasses);
                } catch (HttpResponseException e) {
                    if (e.getStatusCode() == 500) {
                        // occurs in Hannover_MMBS
                        classNumber++;
                        continue;
                    } else {
                        throw e;
                    }
                }
                classNumber++;
            }
            successfulWeeks++;
        } else {
            String url = getScheduleUrl(week, 0, data);
            try {
                parsePage(v, lastChange, null, url, weekName, allClasses);
                successfulWeeks++;
            } catch (HttpResponseException e) {
                lastException = e;
            }
        }
    }
    if (successfulWeeks == 0 && lastException != null) {
        throw lastException;
    }
    v.setClasses(allClasses);
    v.setTeachers(getAllTeachers());
    v.setWebsite(data.optString("website", baseUrl + "/default.htm"));
    return v;
}
Also used : Element(org.jsoup.nodes.Element) SubstitutionSchedule(me.vertretungsplan.objects.SubstitutionSchedule) HttpResponseException(org.apache.http.client.HttpResponseException) IOException(java.io.IOException) Document(org.jsoup.nodes.Document) HttpResponseException(org.apache.http.client.HttpResponseException) IOException(java.io.IOException) JSONException(org.json.JSONException) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException)

Example 4 with CredentialInvalidException

use of me.vertretungsplan.exception.CredentialInvalidException in project substitution-schedule-parser by vertretungsplanme.

the class IphisParser method login.

private Boolean login() throws CredentialInvalidException, IOException {
    final UserPasswordCredential userPasswordCredential = (UserPasswordCredential) credential;
    final String username = userPasswordCredential.getUsername();
    final String password = userPasswordCredential.getPassword();
    JSONObject payload = new JSONObject();
    try {
        payload.put("school", kuerzel);
        payload.put("user", username);
        payload.put("type", scheduleData.getType());
        payload.put("password", password);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    httpPost(api + "/login", "UTF-8", payload.toString(), ContentType.APPLICATION_JSON);
    final String httpResponse = httpPost(api + "/login", "UTF-8", payload.toString(), ContentType.APPLICATION_JSON);
    final JSONObject token;
    try {
        token = new JSONObject(httpResponse);
        final String key = Base64.encodeBase64String(jwt_key.getBytes());
        final Claims jwtToken = Jwts.parser().setSigningKey(key).parseClaimsJws(token.getString("token")).getBody();
        assert jwtToken.getSubject().equals("vertretungsplan.me");
        authToken = token.getString("token");
        website = jwtToken.getIssuer();
        lastUpdate = new LocalDateTime(token.getLong("stand") * 1000);
    } catch (SignatureException | JSONException e) {
        throw new CredentialInvalidException();
    }
    return true;
}
Also used : LocalDateTime(org.joda.time.LocalDateTime) Claims(io.jsonwebtoken.Claims) JSONObject(org.json.JSONObject) JSONException(org.json.JSONException) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) SignatureException(io.jsonwebtoken.SignatureException) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential)

Example 5 with CredentialInvalidException

use of me.vertretungsplan.exception.CredentialInvalidException in project substitution-schedule-parser by vertretungsplanme.

the class SchoolJoomlaParser method executeTask.

@NotNull
private JSONObject executeTask(String task) throws JSONException, IOException, CredentialInvalidException {
    String baseurl = scheduleData.getData().getString(PARAM_BASEURL);
    String username = "";
    String password = "";
    if (credential != null) {
        if (credential instanceof UserPasswordCredential) {
            if (scheduleData.getType() != SubstitutionSchedule.Type.TEACHER) {
                throw new IOException("student schedules only have passwords or no password");
            }
            username = ((UserPasswordCredential) credential).getUsername();
            password = ((UserPasswordCredential) credential).getPassword();
        } else if (credential instanceof PasswordCredential) {
            if (scheduleData.getType() != SubstitutionSchedule.Type.STUDENT) {
                throw new IOException("teacher schedules need a username");
            }
            password = ((PasswordCredential) credential).getPassword();
        }
    }
    String json = httpGet(baseurl + "/components/com_school_mobile/wserv/service" + ".php?select=&user=" + username + "&pw=" + password + "&task=" + task, "UTF-8");
    if (!json.startsWith("{") && json.contains("{")) {
        // sometimes the server gives error messages above the JSON
        json = json.substring(json.indexOf("{"));
    }
    final JSONObject data = new JSONObject(json);
    final int error = data.getInt("error");
    if (error != 0 || data.getJSONArray("errors").length() > 0) {
        switch(error) {
            // wrong teacher password
            case 12:
            case // wrong student password
            17:
                throw new CredentialInvalidException();
            case // teacher auth failed
            3002:
                if (scheduleData.getType() == SubstitutionSchedule.Type.TEACHER) {
                    throw new CredentialInvalidException();
                }
                break;
            default:
                throw new IOException(data.getString("error_desc"));
        }
    }
    return data;
}
Also used : JSONObject(org.json.JSONObject) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) IOException(java.io.IOException) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

CredentialInvalidException (me.vertretungsplan.exception.CredentialInvalidException)6 IOException (java.io.IOException)5 Document (org.jsoup.nodes.Document)4 PasswordCredential (me.vertretungsplan.objects.credential.PasswordCredential)3 UserPasswordCredential (me.vertretungsplan.objects.credential.UserPasswordCredential)3 HttpResponseException (org.apache.http.client.HttpResponseException)3 JSONObject (org.json.JSONObject)3 Element (org.jsoup.nodes.Element)3 ArrayList (java.util.ArrayList)2 SubstitutionSchedule (me.vertretungsplan.objects.SubstitutionSchedule)2 NameValuePair (org.apache.http.NameValuePair)2 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)2 JSONException (org.json.JSONException)2 Claims (io.jsonwebtoken.Claims)1 SignatureException (io.jsonwebtoken.SignatureException)1 BigInteger (java.math.BigInteger)1 URL (java.net.URL)1 InvalidKeyException (java.security.InvalidKeyException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)1