Search in sources :

Example 1 with RemoteLoginException

use of io.kamax.mxisd.exception.RemoteLoginException in project mxisd by kamax-io.

the class AuthController method login.

@RequestMapping(value = logV1Url, method = RequestMethod.POST)
public String login(HttpServletRequest req) {
    try {
        JsonObject reqJsonObject = parser.parse(req.getInputStream());
        // find 3PID in main object
        GsonUtil.findPrimitive(reqJsonObject, "medium").ifPresent(medium -> {
            GsonUtil.findPrimitive(reqJsonObject, "address").ifPresent(address -> {
                log.info("Login request with medium '{}' and address '{}'", medium.getAsString(), address.getAsString());
                strategy.findLocal(medium.getAsString(), address.getAsString()).ifPresent(lookupDataOpt -> {
                    reqJsonObject.addProperty("user", lookupDataOpt.getMxid().getLocalPart());
                    reqJsonObject.remove("medium");
                    reqJsonObject.remove("address");
                });
            });
        });
        // find 3PID in 'identifier' object
        GsonUtil.findObj(reqJsonObject, "identifier").ifPresent(identifier -> {
            GsonUtil.findPrimitive(identifier, "type").ifPresent(type -> {
                if (StringUtils.equals(type.getAsString(), "m.id.thirdparty")) {
                    GsonUtil.findPrimitive(identifier, "medium").ifPresent(medium -> {
                        GsonUtil.findPrimitive(identifier, "address").ifPresent(address -> {
                            log.info("Login request with medium '{}' and address '{}'", medium.getAsString(), address.getAsString());
                            strategy.findLocal(medium.getAsString(), address.getAsString()).ifPresent(lookupDataOpt -> {
                                identifier.addProperty("type", "m.id.user");
                                identifier.addProperty("user", lookupDataOpt.getMxid().getLocalPart());
                                identifier.remove("medium");
                                identifier.remove("address");
                            });
                        });
                    });
                }
                if (StringUtils.equals(type.getAsString(), "m.id.phone")) {
                    GsonUtil.findPrimitive(identifier, "number").ifPresent(number -> {
                        GsonUtil.findPrimitive(identifier, "country").ifPresent(country -> {
                            log.info("Login request with phone '{}'-'{}'", country.getAsString(), number.getAsString());
                            try {
                                PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
                                Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(number.getAsString(), country.getAsString());
                                String canon_phoneNumber = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164).replace("+", "");
                                String medium = "msisdn";
                                strategy.findLocal(medium, canon_phoneNumber).ifPresent(lookupDataOpt -> {
                                    identifier.addProperty("type", "m.id.user");
                                    identifier.addProperty("user", lookupDataOpt.getMxid().getLocalPart());
                                    identifier.remove("country");
                                    identifier.remove("number");
                                });
                            } catch (NumberParseException e) {
                                throw new RuntimeException(e);
                            }
                        });
                    });
                }
            });
        });
        // invoke 'login' on homeserver
        HttpPost httpPost = RestClientUtils.post(resolveProxyUrl(req), gson, reqJsonObject);
        try (CloseableHttpResponse httpResponse = client.execute(httpPost)) {
            // check http status
            int status = httpResponse.getStatusLine().getStatusCode();
            log.info("http status = {}", status);
            if (status != 200) {
                // try to get possible json error message from response
                // otherwise just get returned plain error message
                String errcode = String.valueOf(httpResponse.getStatusLine().getStatusCode());
                String error = EntityUtils.toString(httpResponse.getEntity());
                if (httpResponse.getEntity() != null) {
                    try {
                        JsonObject bodyJson = new JsonParser().parse(error).getAsJsonObject();
                        if (bodyJson.has("errcode")) {
                            errcode = bodyJson.get("errcode").getAsString();
                        }
                        if (bodyJson.has("error")) {
                            error = bodyJson.get("error").getAsString();
                        }
                        throw new RemoteLoginException(status, errcode, error, bodyJson);
                    } catch (JsonSyntaxException e) {
                        log.warn("Response body is not JSON");
                    }
                }
                throw new RemoteLoginException(status, errcode, error);
            }
            // / return response
            JsonObject respJsonObject = parser.parseOptional(httpResponse).get();
            return gson.toJson(respJsonObject);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) PhoneNumberUtil(com.google.i18n.phonenumbers.PhoneNumberUtil) IOException(java.io.IOException) RemoteLoginException(io.kamax.mxisd.exception.RemoteLoginException) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) NumberParseException(com.google.i18n.phonenumbers.NumberParseException) Phonenumber(com.google.i18n.phonenumbers.Phonenumber) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 2 with RemoteLoginException

use of io.kamax.mxisd.exception.RemoteLoginException in project mxisd by kamax-io.

the class AuthManager method proxyLogin.

public String proxyLogin(URI target, String body) {
    JsonObject reqJsonObject = io.kamax.matrix.json.GsonUtil.parseObj(body);
    GsonUtil.findObj(reqJsonObject, IdentifierKey).ifPresent(obj -> {
        GsonUtil.findString(obj, TypeKey).ifPresent(type -> {
            if (StringUtils.equals(type, UserIdTypeValue)) {
                log.info("Login request is User ID type");
                if (cfg.getRewrite().getUser().getRules().isEmpty()) {
                    log.info("No User ID rewrite rules to apply");
                } else {
                    log.info("User ID rewrite rules: checking for a match");
                    String userId = GsonUtil.getStringOrThrow(obj, UserKey);
                    for (AuthenticationConfig.Rule m : cfg.getRewrite().getUser().getRules()) {
                        if (m.getPattern().matcher(userId).matches()) {
                            log.info("Found matching pattern, resolving to 3PID with medium {}", m.getMedium());
                            // Remove deprecated login info on the top object if exists to avoid duplication
                            reqJsonObject.remove(UserKey);
                            obj.addProperty(TypeKey, ThreepidTypeValue);
                            obj.addProperty(ThreepidMediumKey, m.getMedium());
                            obj.addProperty(ThreepidAddressKey, userId);
                            log.info("Rewrite to 3PID done");
                        }
                    }
                    log.info("User ID rewrite rules: done checking rules");
                }
            }
        });
    });
    GsonUtil.findObj(reqJsonObject, IdentifierKey).ifPresent(obj -> {
        GsonUtil.findString(obj, TypeKey).ifPresent(type -> {
            if (StringUtils.equals(type, ThreepidTypeValue)) {
                // Remove deprecated login info if exists to avoid duplication
                reqJsonObject.remove(ThreepidMediumKey);
                reqJsonObject.remove(ThreepidAddressKey);
                GsonUtil.findPrimitive(obj, ThreepidMediumKey).ifPresent(medium -> {
                    GsonUtil.findPrimitive(obj, ThreepidAddressKey).ifPresent(address -> {
                        log.info("Login request with medium '{}' and address '{}'", medium.getAsString(), address.getAsString());
                        strategy.findLocal(medium.getAsString(), address.getAsString()).ifPresent(lookupDataOpt -> {
                            obj.remove(ThreepidMediumKey);
                            obj.remove(ThreepidAddressKey);
                            obj.addProperty(TypeKey, UserIdTypeValue);
                            obj.addProperty(UserKey, lookupDataOpt.getMxid().getLocalPart());
                        });
                    });
                });
            }
            if (StringUtils.equals(type, "m.id.phone")) {
                // Remove deprecated login info if exists to avoid duplication
                reqJsonObject.remove(ThreepidMediumKey);
                reqJsonObject.remove(ThreepidAddressKey);
                GsonUtil.findPrimitive(obj, "number").ifPresent(number -> {
                    GsonUtil.findPrimitive(obj, "country").ifPresent(country -> {
                        log.info("Login request with phone '{}'-'{}'", country.getAsString(), number.getAsString());
                        try {
                            PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
                            Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(number.getAsString(), country.getAsString());
                            String msisdn = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.E164).replace("+", "");
                            String medium = "msisdn";
                            strategy.findLocal(medium, msisdn).ifPresent(lookupDataOpt -> {
                                obj.remove("country");
                                obj.remove("number");
                                obj.addProperty(TypeKey, UserIdTypeValue);
                                obj.addProperty(UserKey, lookupDataOpt.getMxid().getLocalPart());
                            });
                        } catch (NumberParseException e) {
                            log.error("Not a valid phone number");
                            throw new RuntimeException(e);
                        }
                    });
                });
            }
        });
    });
    // invoke 'login' on homeserver
    HttpPost httpPost = RestClientUtils.post(resolveProxyUrl(target), gson, reqJsonObject);
    try (CloseableHttpResponse httpResponse = client.execute(httpPost)) {
        // check http status
        int status = httpResponse.getStatusLine().getStatusCode();
        log.info("http status = {}", status);
        if (status != 200) {
            // try to get possible json error message from response
            // otherwise just get returned plain error message
            String errcode = String.valueOf(httpResponse.getStatusLine().getStatusCode());
            String error = EntityUtils.toString(httpResponse.getEntity());
            if (httpResponse.getEntity() != null) {
                try {
                    JsonObject bodyJson = new JsonParser().parse(error).getAsJsonObject();
                    if (bodyJson.has("errcode")) {
                        errcode = bodyJson.get("errcode").getAsString();
                    }
                    if (bodyJson.has("error")) {
                        error = bodyJson.get("error").getAsString();
                    }
                    throw new RemoteLoginException(status, errcode, error, bodyJson);
                } catch (JsonSyntaxException e) {
                    log.warn("Response body is not JSON");
                }
            }
            throw new RemoteLoginException(status, errcode, error);
        }
        // return response
        HttpEntity entity = httpResponse.getEntity();
        if (Objects.isNull(entity)) {
            log.warn("Expected HS to return data but got nothing");
            return "";
        } else {
            return IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8);
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) HttpEntity(org.apache.http.HttpEntity) PhoneNumberUtil(com.google.i18n.phonenumbers.PhoneNumberUtil) JsonObject(com.google.gson.JsonObject) IOException(java.io.IOException) RemoteLoginException(io.kamax.mxisd.exception.RemoteLoginException) AuthenticationConfig(io.kamax.mxisd.config.AuthenticationConfig) JsonSyntaxException(com.google.gson.JsonSyntaxException) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) NumberParseException(com.google.i18n.phonenumbers.NumberParseException) Phonenumber(com.google.i18n.phonenumbers.Phonenumber) JsonParser(com.google.gson.JsonParser)

Aggregations

NumberParseException (com.google.i18n.phonenumbers.NumberParseException)2 PhoneNumberUtil (com.google.i18n.phonenumbers.PhoneNumberUtil)2 Phonenumber (com.google.i18n.phonenumbers.Phonenumber)2 RemoteLoginException (io.kamax.mxisd.exception.RemoteLoginException)2 IOException (java.io.IOException)2 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)2 HttpPost (org.apache.http.client.methods.HttpPost)2 JsonObject (com.google.gson.JsonObject)1 JsonParser (com.google.gson.JsonParser)1 JsonSyntaxException (com.google.gson.JsonSyntaxException)1 AuthenticationConfig (io.kamax.mxisd.config.AuthenticationConfig)1 HttpEntity (org.apache.http.HttpEntity)1 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)1