diff --git a/src/main/java/io/kamax/mxisd/auth/AuthManager.java b/src/main/java/io/kamax/mxisd/auth/AuthManager.java index 37fcccb..b753c01 100644 --- a/src/main/java/io/kamax/mxisd/auth/AuthManager.java +++ b/src/main/java/io/kamax/mxisd/auth/AuthManager.java @@ -43,8 +43,7 @@ public class AuthManager { private Logger log = LoggerFactory.getLogger(AuthManager.class); - @Autowired - private List providers = new ArrayList<>(); + private List providers; @Autowired private MatrixConfig mxCfg; @@ -52,6 +51,10 @@ public class AuthManager { @Autowired private InvitationManager invMgr; + public AuthManager(List providers) { + this.providers = new ArrayList<>(providers); + } + public UserAuthResult authenticate(String id, String password) { _MatrixID mxid = MatrixID.asAcceptable(id); for (AuthenticatorProvider provider : providers) { diff --git a/src/main/java/io/kamax/mxisd/auth/provider/BackendAuthResult.java b/src/main/java/io/kamax/mxisd/auth/provider/BackendAuthResult.java index a89566d..4d022a3 100644 --- a/src/main/java/io/kamax/mxisd/auth/provider/BackendAuthResult.java +++ b/src/main/java/io/kamax/mxisd/auth/provider/BackendAuthResult.java @@ -49,8 +49,9 @@ public class BackendAuthResult { return r; } - public void fail() { + public BackendAuthResult fail() { success = false; + return this; } public static BackendAuthResult success(String id, UserIdType type, String displayName) { @@ -63,10 +64,11 @@ public class BackendAuthResult { return r; } - public void succeed(String id, String type, String displayName) { + public BackendAuthResult succeed(String id, String type, String displayName) { this.success = true; this.id = new UserID(type, id); this.profile.displayName = displayName; + return this; } private Boolean success; diff --git a/src/main/java/io/kamax/mxisd/backend/google/GoogleProviderBackend.java b/src/main/java/io/kamax/mxisd/backend/google/GoogleProviderBackend.java index 2f1aba5..1f9d542 100644 --- a/src/main/java/io/kamax/mxisd/backend/google/GoogleProviderBackend.java +++ b/src/main/java/io/kamax/mxisd/backend/google/GoogleProviderBackend.java @@ -27,6 +27,7 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import io.kamax.matrix._MatrixID; +import io.kamax.matrix.ThreePid; import io.kamax.mxisd.UserIdType; import io.kamax.mxisd.auth.provider.AuthenticatorProvider; import io.kamax.mxisd.auth.provider.BackendAuthResult; @@ -39,7 +40,9 @@ import org.springframework.stereotype.Component; import java.io.IOException; import java.security.GeneralSecurityException; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Optional; @Component @@ -55,6 +58,15 @@ public class GoogleProviderBackend implements AuthenticatorProvider { return Optional.ofNullable(verifier.verify(data)); } + public List extractThreepids(GoogleIdToken token) { + List tpids = new ArrayList<>(); + tpids.add(new ThreePid("io.kamax.google.id", token.getPayload().getSubject())); + if (token.getPayload().getEmailVerified()) { + tpids.add(new ThreePid("email", token.getPayload().getEmail())); + } + return tpids; + } + @Autowired public GoogleProviderBackend(GoogleConfig cfg, LookupStrategy lookup) { this.cfg = cfg; @@ -81,6 +93,8 @@ public class GoogleProviderBackend implements AuthenticatorProvider { @Override public BackendAuthResult authenticate(_MatrixID mxid, String password) { + BackendAuthResult result = new BackendAuthResult(); + try { return extractToken(password).map(idToken -> { GoogleIdToken.Payload payload = idToken.getPayload(); @@ -93,21 +107,27 @@ public class GoogleProviderBackend implements AuthenticatorProvider { // We validate that the user who authenticated has his Google account associated already return lookup.find("io.kamax.google.id", userId, false).map(r -> { + if (!r.getMxid().equals(mxid)) { - return BackendAuthResult.failure(); + return result.fail(); } // Get profile information from payload + extractThreepids(idToken).forEach(result::withThreePid); String name = (String) payload.get("name"); - return BackendAuthResult.success(mxid.getId(), UserIdType.MatrixID, name); + payload.getUnknownKeys().keySet().forEach(key -> { + log.info("Unknown key in Google profile: {} -> ", key, payload.get(key)); + }); + + return result.succeed(mxid.getId(), UserIdType.MatrixID.getId(), name); }).orElse(BackendAuthResult.failure()); }).orElse(BackendAuthResult.failure()); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } catch (IOException e) { log.error("Unable to authenticate via Google due to network error", e); - return BackendAuthResult.failure(); + return result.fail(); } } diff --git a/src/main/java/io/kamax/mxisd/controller/auth/v1/RegistrationController.java b/src/main/java/io/kamax/mxisd/controller/auth/v1/RegistrationController.java index cdbb886..5f59357 100644 --- a/src/main/java/io/kamax/mxisd/controller/auth/v1/RegistrationController.java +++ b/src/main/java/io/kamax/mxisd/controller/auth/v1/RegistrationController.java @@ -102,7 +102,7 @@ public class RegistrationController { @RequestMapping(path = registerV1Url, method = RequestMethod.POST) public String register(HttpServletRequest req, HttpServletResponse res) { - List ids = new ArrayList<>(); + List ids = new ArrayList<>(); try { JsonObject reqJsonObject = parser.parse(req.getInputStream()); GsonUtil.findObj(reqJsonObject, "auth").ifPresent(auth -> { @@ -121,7 +121,7 @@ public class RegistrationController { } log.info("Google ID: {}", gId); - ids.add(gId); + ids.addAll(google.extractThreepids(token)); auth.addProperty("type", "m.login.dummy"); auth.remove("googleId"); @@ -141,9 +141,12 @@ public class RegistrationController { String body = EntityUtils.toString(httpResponse.getEntity()); JsonObject json = parser.parse(body); if (sc == 200 && json.has("user_id")) { - log.info("User was registered, adding 3PID"); // FIXME we should do this in the backend really + // Required here as synapse doesn't call pass provider on register + log.info("User was registered, adding 3PIDs"); _MatrixID mxid = new MatrixID(json.get("user_id").getAsString()); - pMgr.addThreepid(mxid, new ThreePid("io.kamax.google.id", ids.get(0))); + for (ThreePid tpid : ids) { + pMgr.addThreepid(mxid, tpid); + } } res.setStatus(sc); return body;