Search in sources :

Example 6 with ThreePidSession

use of io.kamax.mxisd.threepid.session.ThreePidSession 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)

Example 7 with ThreePidSession

use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.

the class SessionMananger method validateRemote.

public void validateRemote(String sid, String secret) {
    ThreePidSession session = getSessionIfValidated(sid, secret);
    if (!session.isRemote()) {
        throw new NotAllowedException("Cannot remotely validate a local session");
    }
    log.info("Session {} for {}: Validating remote 3PID session {} on {}", sid, session.getThreePid(), session.getRemoteId(), session.getRemoteServer());
    if (session.isRemoteValidated()) {
        log.info("Session {} for {}: Already remotely validated", sid, session.getThreePid());
        return;
    }
    HttpGet validateReq = new HttpGet(session.getRemoteServer() + "/_matrix/identity/api/v1/3pid/getValidated3pid?sid=" + session.getRemoteId() + "&client_secret=" + session.getRemoteSecret());
    try (CloseableHttpResponse response = client.execute(validateReq)) {
        int status = response.getStatusLine().getStatusCode();
        if (status < 200 || status >= 300) {
            throw new RemoteIdentityServerException("Remote identity server returned with status " + status);
        }
        JsonObject o = new GsonParser().parse(response.getEntity().getContent());
        if (o.has("errcode")) {
            String errcode = o.get("errcode").getAsString();
            if (StringUtils.equals("M_SESSION_NOT_VALIDATED", errcode)) {
                throw new SessionNotValidatedException();
            } else if (StringUtils.equals("M_NO_VALID_SESSION", errcode)) {
                throw new SessionUnknownException();
            } else {
                throw new RemoteIdentityServerException("Unknown error while validating Remote 3PID session: " + errcode + " - " + o.get("error").getAsString());
            }
        }
        if (o.has("validated_at")) {
            ThreePid remoteThreePid = new ThreePid(o.get("medium").getAsString(), o.get("address").getAsString());
            if (!session.getThreePid().equals(remoteThreePid)) {
                // sanity check
                throw new InternalServerError("Local 3PID " + session.getThreePid() + " and remote 3PID " + remoteThreePid + " do not match for session " + session.getId());
            }
            log.info("Session {} for {}: Remotely validated successfully", sid, session.getThreePid());
            session.validateRemote();
            storage.updateThreePidSession(session.getDao());
            log.info("Session {} was updated in storage", sid);
        }
    } catch (IOException e) {
        log.warn("Session {} for {}: Failed to validated remotely on {}: {}", sid, session.getThreePid(), session.getRemoteServer(), e.getMessage());
        throw new RemoteIdentityServerException(e.getMessage());
    }
}
Also used : HttpGet(org.apache.http.client.methods.HttpGet) JsonObject(com.google.gson.JsonObject) 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) ThreePid(io.kamax.matrix.ThreePid)

Example 8 with ThreePidSession

use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.

the class SessionManager method bind.

public SingleLookupReply bind(String sid, String secret, String mxidRaw) {
    // We make sure we have an acceptable User ID
    if (StringUtils.isEmpty(mxidRaw)) {
        throw new IllegalArgumentException("No Matrix User ID provided");
    }
    // We ensure the session was validated
    ThreePidSession session = getSessionIfValidated(sid, secret);
    // We parse the Matrix ID as acceptable
    _MatrixID mxid = MatrixID.asAcceptable(mxidRaw);
    // Only accept binds if the domain matches our own
    if (!StringUtils.equalsIgnoreCase(mxCfg.getDomain(), mxid.getDomain())) {
        throw new NotAllowedException("Only Matrix IDs from domain " + mxCfg.getDomain() + " can be bound");
    }
    log.info("Session {}: Binding of {}:{} to Matrix ID {} is accepted", session.getId(), session.getThreePid().getMedium(), session.getThreePid().getAddress(), mxid.getId());
    SingleLookupRequest request = new SingleLookupRequest();
    request.setType(session.getThreePid().getMedium());
    request.setThreePid(session.getThreePid().getAddress());
    return new SingleLookupReply(request, mxid);
}
Also used : SingleLookupRequest(io.kamax.mxisd.lookup.SingleLookupRequest) SingleLookupReply(io.kamax.mxisd.lookup.SingleLookupReply) NotAllowedException(io.kamax.mxisd.exception.NotAllowedException) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) io.kamax.matrix._MatrixID(io.kamax.matrix._MatrixID)

Example 9 with ThreePidSession

use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.

the class SessionManager method unbind.

public void unbind(JsonObject reqData) {
    _MatrixID mxid;
    try {
        mxid = MatrixID.asAcceptable(GsonUtil.getStringOrThrow(reqData, "mxid"));
    } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
    }
    String sid = GsonUtil.getStringOrNull(reqData, "sid");
    String secret = GsonUtil.getStringOrNull(reqData, "client_secret");
    ThreePid tpid = GsonUtil.get().fromJson(GsonUtil.getObj(reqData, "threepid"), ThreePid.class);
    // We ensure the session was validated
    ThreePidSession session = getSessionIfValidated(sid, secret);
    // As per spec, we can only allow if the provided 3PID matches the validated session
    if (!session.getThreePid().equals(tpid)) {
        throw new BadRequestException("3PID to unbind does not match the one from the validated session");
    }
    // We only allow unbind for the domain we manage, mirroring bind
    if (!StringUtils.equalsIgnoreCase(mxCfg.getDomain(), mxid.getDomain())) {
        throw new NotAllowedException("Only Matrix IDs from domain " + mxCfg.getDomain() + " can be unbound");
    }
    log.info("Session {}: Unbinding of {}:{} to Matrix ID {} is accepted", session.getId(), session.getThreePid().getMedium(), session.getThreePid().getAddress(), mxid.getId());
}
Also used : NotAllowedException(io.kamax.mxisd.exception.NotAllowedException) BadRequestException(io.kamax.mxisd.exception.BadRequestException) ThreePid(io.kamax.matrix.ThreePid) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) io.kamax.matrix._MatrixID(io.kamax.matrix._MatrixID)

Example 10 with ThreePidSession

use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.

the class SessionManager 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");
    }
    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);
            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);
            storage.insertThreePidSession(session.getDao());
            log.info("Stored session {}", sessionId);
            log.info("Session {} for {}: sending validation notification", sessionId, tpid);
            notifMgr.sendForValidation(session);
            return sessionId;
        }
    }
}
Also used : IThreePidSessionDao(io.kamax.mxisd.storage.dao.IThreePidSessionDao) NotAllowedException(io.kamax.mxisd.exception.NotAllowedException) ThreePidSession(io.kamax.mxisd.threepid.session.ThreePidSession) PolicyTemplate(io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate)

Aggregations

ThreePidSession (io.kamax.mxisd.threepid.session.ThreePidSession)10 IThreePidSession (io.kamax.mxisd.threepid.session.IThreePidSession)5 ThreePid (io.kamax.matrix.ThreePid)3 io.kamax.matrix._MatrixID (io.kamax.matrix._MatrixID)3 PolicySource (io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate.PolicySource)3 NotAllowedException (io.kamax.mxisd.exception.NotAllowedException)3 GsonParser (io.kamax.mxisd.util.GsonParser)3 IOException (java.io.IOException)3 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)3 JsonObject (com.google.gson.JsonObject)2 Phonenumber (com.google.i18n.phonenumbers.Phonenumber)2 PolicyTemplate (io.kamax.mxisd.config.SessionConfig.Policy.PolicyTemplate)2 NotificationManager (io.kamax.mxisd.notification.NotificationManager)2 IThreePidSessionDao (io.kamax.mxisd.storage.dao.IThreePidSessionDao)2 HttpPost (org.apache.http.client.methods.HttpPost)2 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)2 Logger (org.slf4j.Logger)2 NumberParseException (com.google.i18n.phonenumbers.NumberParseException)1 ServerSetupTest (com.icegreen.greenmail.util.ServerSetupTest)1 MatrixID (io.kamax.matrix.MatrixID)1