Search in sources :

Example 1 with PolicySource

use of io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource in project mxisd by kamax-io.

the class SessionMananger method create.

public String create(String server, ThreePid tpid, String secret, int attempt, String nextLink) {
    PolicyTemplate policy = cfg.getPolicy().getValidation();
    if (!policy.isEnabled()) {
        throw new NotAllowedException("Validating 3PID is disabled globally");
    }
    synchronized (this) {
        log.info("Server {} is asking to create session for {} (Attempt #{}) - Next link: {}", server, tpid, attempt, nextLink);
        Optional<IThreePidSessionDao> dao = storage.findThreePidSession(tpid, secret);
        if (dao.isPresent()) {
            ThreePidSession session = new ThreePidSession(dao.get());
            log.info("We already have a session for {}: {}", tpid, session.getId());
            if (session.getAttempt() < attempt) {
                log.info("Received attempt {} is greater than stored attempt {}, sending validation communication", attempt, session.getAttempt());
                notifMgr.sendForValidation(session);
                log.info("Sent validation notification to {}", tpid);
                session.increaseAttempt();
                storage.updateThreePidSession(session.getDao());
            }
            return session.getId();
        } else {
            log.info("No existing session for {}", tpid);
            boolean isLocal = isLocal(tpid);
            log.info("Is 3PID bound to local domain? {}", isLocal);
            // This might need a configuration by medium type?
            PolicySource policySource = policy.forIf(isLocal);
            if (!policySource.isEnabled() || (!policySource.toLocal() && !policySource.toRemote())) {
                log.info("Session for {}: cancelled due to policy", tpid);
                throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
            }
            String sessionId;
            do {
                sessionId = Long.toString(System.currentTimeMillis());
            } while (storage.getThreePidSession(sessionId).isPresent());
            String token = RandomStringUtils.randomNumeric(6);
            ThreePidSession session = new ThreePidSession(sessionId, server, tpid, secret, attempt, nextLink, token);
            log.info("Generated new session {} to validate {} from server {}", sessionId, tpid, server);
            // This might need a configuration by medium type?
            if (policySource.toLocal()) {
                log.info("Session {} for {}: sending local validation notification", sessionId, tpid);
                notifMgr.sendForValidation(session);
            } else {
                log.info("Session {} for {}: sending remote-only validation notification", sessionId, tpid);
                notifMgr.sendforRemoteValidation(session);
            }
            storage.insertThreePidSession(session.getDao());
            log.info("Stored session {}", sessionId, tpid, server);
            return sessionId;
        }
    }
}
Also used : IThreePidSessionDao(io.kamax.mxisd.storage.dao.IThreePidSessionDao) PolicySource(io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) IThreePidSession(io.kamax.mxisd.threepid.session.IThreePidSession) PolicyTemplate(io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate)

Example 2 with PolicySource

use of io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource in project mxisd by kamax-io.

the class SessionMananger method createRemote.

public IThreePidSession createRemote(String sid, String secret) {
    ThreePidSession session = getSessionIfValidated(sid, secret);
    log.info("Creating remote 3PID session for {} with local session [{}] to {}", session.getThreePid(), sid);
    boolean isLocal = isLocal(session.getThreePid());
    PolicySource policy = cfg.getPolicy().getValidation().forIf(isLocal);
    if (!policy.isEnabled() || !policy.toRemote()) {
        throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
    }
    log.info("Remote 3PID is allowed by policy");
    List<String> servers = mxCfg.getIdentity().getServers(policy.getToRemote().getServer());
    if (servers.isEmpty()) {
        throw new FeatureNotAvailable("Remote 3PID sessions are enabled but server list is " + "misconstrued (invalid ID or empty list");
    }
    String is = servers.get(0);
    String url = IdentityServerUtils.findIsUrlForDomain(is).orElseThrow(() -> new InternalServerError(is + " could not be resolved to an Identity server"));
    log.info("Will use IS endpoint {}", url);
    String remoteSecret = session.isRemote() ? session.getRemoteSecret() : RandomStringUtils.randomAlphanumeric(16);
    JsonObject body = new JsonObject();
    body.addProperty("client_secret", remoteSecret);
    body.addProperty(session.getThreePid().getMedium(), session.getThreePid().getAddress());
    body.addProperty("send_attempt", session.increaseAndGetRemoteAttempt());
    if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium())) {
        try {
            Phonenumber.PhoneNumber msisdn = phoneUtil.parse("+" + session.getThreePid().getAddress(), null);
            String country = phoneUtil.getRegionCodeForNumber(msisdn).toUpperCase();
            body.addProperty("phone_number", phoneUtil.format(msisdn, PhoneNumberUtil.PhoneNumberFormat.NATIONAL));
            body.addProperty("country", country);
        } catch (NumberParseException e) {
            throw new InternalServerError(e);
        }
    } else {
        body.addProperty(session.getThreePid().getMedium(), session.getThreePid().getAddress());
    }
    log.info("Requesting remote session with attempt {}", session.getRemoteAttempt());
    HttpPost tokenReq = RestClientUtils.post(url + "/_matrix/identity/api/v1/validate/" + session.getThreePid().getMedium() + "/requestToken", body);
    try (CloseableHttpResponse response = client.execute(tokenReq)) {
        int status = response.getStatusLine().getStatusCode();
        if (status < 200 || status >= 300) {
            JsonObject obj = parser.parseOptional(response).orElseThrow(() -> new RemoteIdentityServerException("Status " + status));
            throw new RemoteIdentityServerException(obj.get("errcode").getAsString() + ": " + obj.get("error").getAsString());
        }
        RequestTokenResponse data = new GsonParser().parse(response, RequestTokenResponse.class);
        log.info("Remote Session ID: {}", data.getSid());
        session.setRemoteData(url, data.getSid(), remoteSecret, 1);
        storage.updateThreePidSession(session.getDao());
        log.info("Updated Session {} with remote data", sid);
        return session;
    } catch (IOException e) {
        log.warn("Failed to create remote session with {} for {}: {}", url, session.getThreePid(), e.getMessage());
        throw new RemoteIdentityServerException(e.getMessage());
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) JsonObject(com.google.gson.JsonObject) RequestTokenResponse(io.kamax.mxisd.controller.identity.v1.io.RequestTokenResponse) IOException(java.io.IOException) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) IThreePidSession(io.kamax.mxisd.threepid.session.IThreePidSession) GsonParser(io.kamax.mxisd.util.GsonParser) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) NumberParseException(com.google.i18n.phonenumbers.NumberParseException) PolicySource(io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource) Phonenumber(com.google.i18n.phonenumbers.Phonenumber)

Example 3 with PolicySource

use of io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource in project mxisd by kamax-io.

the class SessionMananger method validate.

public ValidationResult validate(String sid, String secret, String token) {
    ThreePidSession session = getSession(sid, secret);
    log.info("Attempting validation for session {} from {}", session.getId(), session.getServer());
    boolean isLocal = isLocal(session.getThreePid());
    PolicySource policy = cfg.getPolicy().getValidation().forIf(isLocal);
    if (!policy.isEnabled()) {
        throw new NotAllowedException("Validating " + (isLocal ? "local" : "remote") + " 3PID is not allowed");
    }
    if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium()) && session.isValidated() && session.isRemote()) {
        submitRemote(session, token);
        session.validateRemote();
        return new ValidationResult(session, false);
    }
    session.validate(token);
    storage.updateThreePidSession(session.getDao());
    log.info("Session {} has been validated locally", session.getId());
    if (ThreePidMedium.PhoneNumber.is(session.getThreePid().getMedium()) && session.isValidated() && policy.toRemote()) {
        createRemote(sid, secret);
        // FIXME make the message configurable/customizable (templates?)
        throw new MessageForClientException("You will receive a NEW code from another number. Enter it below");
    }
    // FIXME definitely doable in a nicer way
    ValidationResult r = new ValidationResult(session, policy.toRemote());
    if (!policy.toLocal()) {
        r.setNextUrl(RemoteIdentityAPIv1.getRequestToken(sid, secret));
    } else {
        session.getNextLink().ifPresent(r::setNextUrl);
    }
    return r;
}
Also used : NotificationManager(io.kamax.mxisd.notification.NotificationManager) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) GsonParser(io.kamax.mxisd.util.GsonParser) Logger(org.slf4j.Logger) Phonenumber(com.google.i18n.phonenumbers.Phonenumber) PolicySource(io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) IThreePidSession(io.kamax.mxisd.threepid.session.IThreePidSession)

Aggregations

PolicySource (io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource)3 IThreePidSession (io.kamax.mxisd.threepid.session.IThreePidSession)3 ThreePidSession (io.kamax.mxisd.threepid.session.ThreePidSession)3 Phonenumber (com.google.i18n.phonenumbers.Phonenumber)2 GsonParser (io.kamax.mxisd.util.GsonParser)2 JsonObject (com.google.gson.JsonObject)1 NumberParseException (com.google.i18n.phonenumbers.NumberParseException)1 PolicyTemplate (io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate)1 RequestTokenResponse (io.kamax.mxisd.controller.identity.v1.io.RequestTokenResponse)1 NotificationManager (io.kamax.mxisd.notification.NotificationManager)1 IThreePidSessionDao (io.kamax.mxisd.storage.dao.IThreePidSessionDao)1 IOException (java.io.IOException)1 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)1 HttpPost (org.apache.http.client.methods.HttpPost)1 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)1 Logger (org.slf4j.Logger)1