Move config properties to central location and tolerate missing config

This commit is contained in:
Andrew Guibert 2018-05-23 15:02:47 -05:00
parent 2320d5d4ab
commit 55431dcb91
8 changed files with 134 additions and 86 deletions

View File

@ -4,8 +4,4 @@ import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class AuthApp extends Application {
public static final String HTTPS_AUTH_SERVICE = "https://localhost:8482/auth-service";
public static final String FRONTEND_URL = "http://localhost:12000/login";
}
public class AuthApp extends Application {}

View File

@ -0,0 +1,36 @@
package org.libertybikes.auth.service;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.libertybikes.auth.service.github.GitHubAuth;
import org.libertybikes.auth.service.google.GoogleAuth;
@Path("/")
@ApplicationScoped
public class AuthTypes {
@Inject
ConfigBean config;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Set<String> endpoints() {
Set<String> types = new HashSet<>();
if (config.checkGitHubConfig())
types.add(GitHubAuth.class.getSimpleName());
if (config.checkGoogleConfig())
types.add(GoogleAuth.class.getSimpleName());
return types;
}
}

View File

@ -0,0 +1,78 @@
package org.libertybikes.auth.service;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Dependent
public class ConfigBean {
// REQUIRED GOOGLE SETTINGS
public static final String GOOGLE_KEY = "googleOAuthConsumerKey";
public static final String GOOGLE_SECRET = "googleOAuthConsumerSecret";
// REQUIRED GITHUB SETTINGS
public static final String GITHUB_KEY = "github_key";
public static final String GITHUB_SECRET = "github_secret";
@Inject
@ConfigProperty(name = "auth_url", defaultValue = "https://localhost:8482/auth-service")
public String authUrl;
@Inject
@ConfigProperty(name = "frontend_url", defaultValue = "http://localhost:12000/login")
public String frontendUrl;
// Give the required config properties default values so that people don't need to set up
// all auth types in order to use any of them (app deployment fails if any config can't be injected otherwise)
@Inject
@ConfigProperty(name = GITHUB_KEY, defaultValue = "")
public String github_key;
@Inject
@ConfigProperty(name = GITHUB_SECRET, defaultValue = "")
public String github_secret;
@Inject
@ConfigProperty(name = GOOGLE_KEY, defaultValue = "")
public String google_key;
@Inject
@ConfigProperty(name = GOOGLE_SECRET, defaultValue = "")
public String google_secret;
@PostConstruct
public void validate() {
checkGitHubConfig();
checkGoogleConfig();
}
public boolean checkGitHubConfig() {
boolean success = true;
if (github_key.isEmpty()) {
success = false;
System.out.println("WARN: " + GITHUB_KEY + " not set, GitHub auth will not be available...");
}
if (github_secret.isEmpty()) {
success = false;
System.out.println("WARN: " + GITHUB_SECRET + " not set, GitHub auth will not be available...");
}
return success;
}
public boolean checkGoogleConfig() {
boolean success = true;
if (google_key.isEmpty()) {
success = false;
System.out.println("WARN: " + GOOGLE_KEY + " not set, GitHub auth will not be available...");
}
if (google_secret.isEmpty()) {
success = false;
System.out.println("WARN: " + GOOGLE_SECRET + " not set, GitHub auth will not be available...");
}
return success;
}
}

View File

@ -33,10 +33,6 @@ public abstract class JwtAuth {
@ConfigProperty(name = "jwtKeyStoreAlias", defaultValue = "bike")
String keyStoreAlias;
@Inject
@ConfigProperty(name = "auth_url", defaultValue = AuthApp.HTTPS_AUTH_SERVICE)
String authUrl;
protected static Key signingKey = null;
/**

View File

@ -11,8 +11,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.libertybikes.auth.service.AuthApp;
import org.libertybikes.auth.service.ConfigBean;
@Path("/GitHubAuth")
@ApplicationScoped
@ -21,12 +20,7 @@ public class GitHubAuth {
private final static String GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize";
@Inject
@ConfigProperty(name = "github_key")
String key;
@Inject
@ConfigProperty(name = "auth_url", defaultValue = AuthApp.HTTPS_AUTH_SERVICE)
String authUrl;
ConfigBean config;
@GET
public Response getAuthURL(@Context HttpServletRequest request) {
@ -35,10 +29,10 @@ public class GitHubAuth {
request.getSession().setAttribute("github", randomCode);
// GitHub will tell the users browser to go to this address once they are done authing.
String callbackURL = authUrl + "/GitHubCallback";
String callbackURL = config.authUrl + "/GitHubCallback";
// send the user to GitHub to be authenticated
String redirectURL = GITHUB_AUTH_URL + "?client_id=" + key + "&redirect_url=" + callbackURL + "&scope=user:email&state=" + randomCode;
String redirectURL = GITHUB_AUTH_URL + "?client_id=" + config.github_key + "&redirect_url=" + callbackURL + "&scope=user:email&state=" + randomCode;
return Response.temporaryRedirect(new URI(redirectURL)).build();
} catch (Exception e) {
e.printStackTrace();

View File

@ -1,8 +1,6 @@
package org.libertybikes.auth.service.github;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
@ -15,15 +13,13 @@ import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.Validator;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.libertybikes.auth.service.AuthApp;
import org.libertybikes.auth.service.ConfigBean;
import org.libertybikes.auth.service.JwtAuth;
import org.libertybikes.auth.service.github.GitHubOAuthAPI.GithubTokenResponse;
import org.libertybikes.auth.service.github.GitHubUserAPI.EmailData;
@ -39,38 +35,11 @@ public class GitHubCallback extends JwtAuth {
GitHubUserAPI githubUserAPI;
@Inject
@ConfigProperty(name = "github_key")
String key;
@Inject
@ConfigProperty(name = "github_secret")
String secret;
@Inject
@ConfigProperty(name = "frontend_url", defaultValue = AuthApp.FRONTEND_URL)
String frontendUrl;
@Inject
@ConfigProperty(name = "auth_url", defaultValue = AuthApp.HTTPS_AUTH_SERVICE)
String authUrl;
ConfigBean config;
@Inject
Validator validator;
@GET
@Path("/test")
@Valid
public GithubTokenResponse testToken() {
for (Method m : getClass().getMethods()) {
System.out.println("@AGG found method: " + m.getName());
for (Annotation a : m.getAnnotations())
System.out.println(" anno=" + a);
}
GithubTokenResponse badToken = new GithubTokenResponse();
badToken.access_token = "bogus";
return badToken;
}
// TODO: need to manually validate return types because the @Valid annotation on our MP Rest Client interface
// is getting lost when the instance is injected into this class.
private void validate(Object obj) {
@ -87,15 +56,10 @@ public class GitHubCallback extends JwtAuth {
String githubCode = request.getParameter("code");
String randomCode = (String) request.getSession().getAttribute("github");
String thisURL = authUrl + "/GitHubCallback";
String thisURL = config.authUrl + "/GitHubCallback";
// First send the user through GitHub OAuth to get permission to read their email address
GithubTokenResponse response = githubOAuthAPI.accessToken(key, secret, githubCode, thisURL, randomCode);
// for (Method m : githubOAuthAPI.getClass().getMethods()) {
// System.out.println("@AGG found method: " + m.getName());
// for (Annotation a : m.getAnnotations())
// System.out.println(" anno=" + a);
// }
GithubTokenResponse response = githubOAuthAPI.accessToken(config.github_key, config.github_secret, githubCode, thisURL, randomCode);
validate(response);
System.out.println("GitHub access token: " + response.access_token);
@ -118,7 +82,7 @@ public class GitHubCallback extends JwtAuth {
claims.put("id", "GITHUB:" + primaryEmail);
claims.put("upn", primaryEmail);
claims.put("email", primaryEmail);
return Response.temporaryRedirect(new URI(frontendUrl + "/" + createJwt(claims))).build();
return Response.temporaryRedirect(new URI(config.frontendUrl + "/" + createJwt(claims))).build();
} catch (Exception e) {
e.printStackTrace();
return fail();
@ -126,6 +90,6 @@ public class GitHubCallback extends JwtAuth {
}
private Response fail() throws URISyntaxException {
return Response.temporaryRedirect(new URI(frontendUrl)).build();
return Response.temporaryRedirect(new URI(config.frontendUrl)).build();
}
}

View File

@ -11,8 +11,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.libertybikes.auth.service.AuthApp;
import org.libertybikes.auth.service.ConfigBean;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.http.HttpTransport;
@ -25,16 +24,7 @@ import com.google.api.client.json.jackson2.JacksonFactory;
public class GoogleAuth {
@Inject
@ConfigProperty(name = "googleOAuthConsumerKey")
String key;
@Inject
@ConfigProperty(name = "googleOAuthConsumerSecret")
String secret;
@Inject
@ConfigProperty(name = "auth_url", defaultValue = AuthApp.HTTPS_AUTH_SERVICE)
String authUrl;
ConfigBean config;
@GET
public Response getAuthURL(@Context HttpServletRequest request) {
@ -42,13 +32,13 @@ public class GoogleAuth {
JsonFactory jsonFactory = new JacksonFactory();
HttpTransport httpTransport = new NetHttpTransport();
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(httpTransport, jsonFactory, key, secret, Arrays
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow(httpTransport, jsonFactory, config.google_key, config.google_secret, Arrays
.asList("https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/userinfo.email"));
try {
// google will tell the users browser to go to this address once
// they are done authing.
String callbackURL = authUrl + "/GoogleCallback";
String callbackURL = config.authUrl + "/GoogleCallback";
request.getSession().setAttribute("google", flow);
String authorizationUrl = flow.newAuthorizationUrl().setRedirectUri(callbackURL).build();

View File

@ -19,8 +19,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.libertybikes.auth.service.AuthApp;
import org.libertybikes.auth.service.ConfigBean;
import org.libertybikes.auth.service.JwtAuth;
import com.google.api.client.auth.oauth2.Credential;
@ -38,12 +37,7 @@ public class GoogleCallback extends JwtAuth {
private static final Jsonb jsonb = JsonbBuilder.create();
@Inject
@ConfigProperty(name = "frontend_url", defaultValue = AuthApp.FRONTEND_URL)
String frontendUrl;
@Inject
@ConfigProperty(name = "auth_url", defaultValue = AuthApp.HTTPS_AUTH_SERVICE)
String authUrl;
ConfigBean config;
public static class GoogleUser {
public String name;
@ -103,7 +97,7 @@ public class GoogleCallback extends JwtAuth {
String code = request.getParameter("code");
//now we need to invoke the access_token endpoint to swap the code for a token.
String callbackURL = authUrl + "/GoogleCallback";
String callbackURL = config.authUrl + "/GoogleCallback";
GoogleTokenResponse gResponse;
Map<String, String> claims = new HashMap<String, String>();
@ -116,10 +110,10 @@ public class GoogleCallback extends JwtAuth {
// if auth key was no longer valid, we won't build a JWT. Redirect back to start.
if (!"true".equals(claims.get("valid"))) {
return Response.temporaryRedirect(new URI(frontendUrl)).build();
return Response.temporaryRedirect(new URI(config.frontendUrl)).build();
} else {
String newJwt = createJwt(claims);
return Response.temporaryRedirect(new URI(frontendUrl + "/" + newJwt)).build();
return Response.temporaryRedirect(new URI(config.frontendUrl + "/" + newJwt)).build();
}
}
}