Research with Google auth integration
This commit is contained in:
@@ -102,6 +102,9 @@ dependencies {
|
||||
compile 'com.sun.mail:javax.mail:1.5.6'
|
||||
compile 'javax.mail:javax.mail-api:1.5.6'
|
||||
|
||||
// Google Client APIs
|
||||
compile 'com.google.api-client:google-api-client:1.23.0'
|
||||
|
||||
// Google Firebase Authentication backend
|
||||
compile 'com.google.firebase:firebase-admin:5.3.0'
|
||||
|
||||
|
@@ -59,6 +59,7 @@ public class AuthManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
log.info("Attempting auth with " + provider.getClass().getSimpleName());
|
||||
BackendAuthResult result = provider.authenticate(mxid, password);
|
||||
if (result.isSuccess()) {
|
||||
|
||||
|
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* mxisd - Matrix Identity Server Daemon
|
||||
* Copyright (C) 2018 Kamax Sàrl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.backend.google;
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
|
||||
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
|
||||
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._MatrixID;
|
||||
import io.kamax.mxisd.ThreePid;
|
||||
import io.kamax.mxisd.UserIdType;
|
||||
import io.kamax.mxisd.auth.provider.AuthenticatorProvider;
|
||||
import io.kamax.mxisd.auth.provider.BackendAuthResult;
|
||||
import io.kamax.mxisd.config.GoogleConfig;
|
||||
import io.kamax.mxisd.config.MatrixConfig;
|
||||
import io.kamax.mxisd.lookup.SingleLookupReply;
|
||||
import io.kamax.mxisd.lookup.SingleLookupRequest;
|
||||
import io.kamax.mxisd.lookup.ThreePidMapping;
|
||||
import io.kamax.mxisd.lookup.provider.IThreePidProvider;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class GoogleProviderBackend implements AuthenticatorProvider, IThreePidProvider {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(GoogleProviderBackend.class);
|
||||
private final GoogleConfig cfg;
|
||||
private final MatrixConfig mxCfg;
|
||||
|
||||
private GoogleIdTokenVerifier verifier;
|
||||
|
||||
@Autowired
|
||||
public GoogleProviderBackend(GoogleConfig cfg, MatrixConfig mxCfg) {
|
||||
this.cfg = cfg;
|
||||
this.mxCfg = mxCfg;
|
||||
|
||||
if (isEnabled()) {
|
||||
try {
|
||||
HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
|
||||
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
|
||||
|
||||
verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
|
||||
.setAudience(Collections.singletonList(cfg.getClient().getId()))
|
||||
.build();
|
||||
} catch (IOException | GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return cfg.isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<SingleLookupReply> find(SingleLookupRequest request) {
|
||||
if (!StringUtils.equals(cfg.getMedium(), request.getType())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(new SingleLookupReply(request, new MatrixID(cfg.getPrefix() + request.getThreePid(), mxCfg.getDomain())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ThreePidMapping> populate(List<ThreePidMapping> mappings) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackendAuthResult authenticate(_MatrixID mxid, String password) {
|
||||
if (!StringUtils.startsWith(mxid.getLocalPart(), cfg.getPrefix())) {
|
||||
return BackendAuthResult.failure();
|
||||
}
|
||||
|
||||
BackendAuthResult result = new BackendAuthResult();
|
||||
result.withThreePid(new ThreePid(cfg.getMedium(), mxid.getLocalPart().replace(cfg.getPrefix(), "")));
|
||||
result.succeed(mxid.getId(), UserIdType.MatrixID.getId(), null);
|
||||
return result;
|
||||
|
||||
/*
|
||||
try {
|
||||
log.info("ID Token: {}", password);
|
||||
GoogleIdToken idToken = verifier.verify(password);
|
||||
if (idToken != null) {
|
||||
BackendAuthResult
|
||||
GoogleIdToken.Payload payload = idToken.getPayload();
|
||||
|
||||
// Get user identifier
|
||||
String userId = payload.getSubject();
|
||||
|
||||
// Get profile information from payload
|
||||
String email = payload.getEmail();
|
||||
if (payload.getEmailVerified()) {
|
||||
|
||||
}
|
||||
String name = (String) payload.get("name");
|
||||
String pictureUrl = (String) payload.get("picture");
|
||||
String locale = (String) payload.get("locale");
|
||||
String familyName = (String) payload.get("family_name");
|
||||
String givenName = (String) payload.get("given_name");
|
||||
|
||||
return BackendAuthResult.success(userId, UserIdType.Localpart, name);
|
||||
} else {
|
||||
log.info("Not a valid Google token");
|
||||
return 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();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
107
src/main/java/io/kamax/mxisd/config/GoogleConfig.java
Normal file
107
src/main/java/io/kamax/mxisd/config/GoogleConfig.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* mxisd - Matrix Identity Server Daemon
|
||||
* Copyright (C) 2018 Kamax Sàrl
|
||||
*
|
||||
* https://www.kamax.io/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.kamax.mxisd.config;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties("google")
|
||||
public class GoogleConfig {
|
||||
|
||||
public static class Client {
|
||||
|
||||
private String id;
|
||||
private String secret;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(GoogleConfig.class);
|
||||
|
||||
private boolean enabled;
|
||||
private Client client = new Client();
|
||||
private String medium = "io.kamax.google.id";
|
||||
private String prefix = "google_";
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
return client;
|
||||
}
|
||||
|
||||
public void setClient(Client client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
public String getMedium() {
|
||||
return medium;
|
||||
}
|
||||
|
||||
public void setMedium(String medium) {
|
||||
this.medium = medium;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void build() {
|
||||
log.info("--- Google config ---");
|
||||
log.info("Enabled: {}", isEnabled());
|
||||
log.info("Client ID: {}", getClient().getId());
|
||||
log.info("Client secret set? {}", StringUtils.isNotBlank(getClient().getSecret()));
|
||||
log.info("3PID medium: {}", getMedium());
|
||||
log.info("MXID prefix: {}", getPrefix());
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user