use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.
the class SessionMananger method bind.
public void bind(String sid, String secret, String mxidRaw) {
_MatrixID mxid = new MatrixID(mxidRaw);
ThreePidSession session = getSessionIfValidated(sid, secret);
if (!session.isRemote()) {
log.info("Session {} for {}: MXID {} was bound locally", sid, session.getThreePid(), mxid);
return;
}
log.info("Session {} for {}: MXID {} bind is remote", sid, session.getThreePid(), mxid);
if (!session.isRemoteValidated()) {
log.error("Session {} for {}: Not validated remotely", sid, session.getThreePid());
throw new SessionNotValidatedException();
}
log.info("Session {} for {}: Performing remote bind", sid, session.getThreePid());
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(Arrays.asList(new BasicNameValuePair("sid", session.getRemoteId()), new BasicNameValuePair("client_secret", session.getRemoteSecret()), new BasicNameValuePair("mxid", mxid.getId())), StandardCharsets.UTF_8);
HttpPost bindReq = new HttpPost(session.getRemoteServer() + "/_matrix/identity/api/v1/3pid/bind");
bindReq.setEntity(entity);
try (CloseableHttpResponse response = client.execute(bindReq)) {
int status = response.getStatusLine().getStatusCode();
if (status < 200 || status >= 300) {
String body = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
log.error("Session {} for {}: Remote IS {} failed when trying to bind {} for remote session {}\n{}", sid, session.getThreePid(), session.getRemoteServer(), mxid, session.getRemoteId(), body);
throw new RemoteIdentityServerException(body);
}
log.error("Session {} for {}: MXID {} was bound remotely", sid, session.getThreePid(), mxid);
} catch (IOException e) {
log.error("Session {} for {}: I/O Error when trying to bind mxid {}", sid, session.getThreePid(), mxid);
throw new RemoteIdentityServerException(e.getMessage());
}
}
use of io.kamax.mxisd.threepid.session.ThreePidSession 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;
}
}
}
use of io.kamax.mxisd.threepid.session.ThreePidSession 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());
}
}
use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.
the class EmailNotificationTest method forValidation.
@Test
public void forValidation() throws MessagingException, IOException {
gm.setUser(user, user);
String token = RandomStringUtils.randomAlphanumeric(128);
ThreePidSession session = new ThreePidSession("", "", new ThreePid(ThreePidMedium.Email.getId(), target), "", 1, "", token);
m.getNotif().sendForValidation(session);
assertEquals(1, gm.getReceivedMessages().length);
MimeMessage msg = gm.getReceivedMessages()[0];
assertEquals(1, msg.getFrom().length);
assertEquals(senderNameEncoded, msg.getFrom()[0].toString());
assertEquals(1, msg.getRecipients(Message.RecipientType.TO).length);
// We just check on the text/plain one. HTML is multipart and it's difficult so we skip
MimeMultipart content = (MimeMultipart) msg.getContent();
MimeBodyPart mbp = (MimeBodyPart) content.getBodyPart(0);
String mbpContent = mbp.getContent().toString();
assertTrue(mbpContent.contains(token));
}
use of io.kamax.mxisd.threepid.session.ThreePidSession in project mxisd by kamax-io.
the class SessionManager method validate.
public ValidationResult validate(String sid, String secret, String token) {
log.info("Validating session {}", sid);
ThreePidSession session = getSession(sid, secret);
log.info("Session {} is from {}", session.getId(), session.getServer());
session.validate(token);
storage.updateThreePidSession(session.getDao());
log.info("Session {} has been validated", session.getId());
ValidationResult r = new ValidationResult(session);
session.getNextLink().ifPresent(r::setNextUrl);
return r;
}
Aggregations