Twitter auth option

This commit is contained in:
Andrew Guibert 2018-05-23 18:11:37 -05:00
parent 55431dcb91
commit c0454efede
11 changed files with 195 additions and 22 deletions

View File

@ -17,6 +17,7 @@ liberty {
dependencies {
compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.0'
compile group: 'com.google.api-client', name: 'google-api-client', version: '1.23.0'
compile group: 'org.twitter4j', name: 'twitter4j-core', version: '4.0.+'
}

View File

@ -1,6 +1,5 @@
package org.libertybikes.auth.service;
import java.util.HashSet;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
@ -10,9 +9,6 @@ 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 {
@ -23,14 +19,7 @@ public class AuthTypes {
@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;
return config.getConfiguredTypes();
}
}

View File

@ -0,0 +1,6 @@
package org.libertybikes.auth.service;
import javax.enterprise.inject.Stereotype;
@Stereotype
public @interface BeanDefiner {}

View File

@ -1,12 +1,19 @@
package org.libertybikes.auth.service;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.libertybikes.auth.service.github.GitHubAuth;
import org.libertybikes.auth.service.google.GoogleAuth;
import org.libertybikes.auth.service.twitter.TwitterAuth;
@Dependent
@Singleton
@BeanDefiner
public class ConfigBean {
// REQUIRED GOOGLE SETTINGS
@ -17,6 +24,10 @@ public class ConfigBean {
public static final String GITHUB_KEY = "github_key";
public static final String GITHUB_SECRET = "github_secret";
// REQUIRED TWITTER SETTINGS
public static final String TWITTER_KEY = "twitter_key";
public static final String TWITTER_SECRET = "twitter_secret";
@Inject
@ConfigProperty(name = "auth_url", defaultValue = "https://localhost:8482/auth-service")
public String authUrl;
@ -43,13 +54,32 @@ public class ConfigBean {
@ConfigProperty(name = GOOGLE_SECRET, defaultValue = "")
public String google_secret;
@Inject
@ConfigProperty(name = TWITTER_KEY, defaultValue = "")
public String twitter_key;
@Inject
@ConfigProperty(name = TWITTER_SECRET, defaultValue = "")
public String twitter_secret;
@PostConstruct
public void validate() {
checkGitHubConfig();
checkGoogleConfig();
}
public boolean checkGitHubConfig() {
public Set<String> getConfiguredTypes() {
Set<String> types = new HashSet<>();
if (checkGitHubConfig())
types.add(GitHubAuth.class.getSimpleName());
if (checkGoogleConfig())
types.add(GoogleAuth.class.getSimpleName());
if (checkTwitterConfig())
types.add(TwitterAuth.class.getSimpleName());
return types;
}
private boolean checkGitHubConfig() {
boolean success = true;
if (github_key.isEmpty()) {
success = false;
@ -62,15 +92,28 @@ public class ConfigBean {
return success;
}
public boolean checkGoogleConfig() {
private 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...");
System.out.println("WARN: " + GOOGLE_KEY + " not set, Google 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...");
System.out.println("WARN: " + GOOGLE_SECRET + " not set, Google auth will not be available...");
}
return success;
}
private boolean checkTwitterConfig() {
boolean success = true;
if (twitter_key.isEmpty()) {
success = false;
System.out.println("WARN: " + TWITTER_KEY + " not set, Twitter auth will not be available...");
}
if (twitter_secret.isEmpty()) {
success = false;
System.out.println("WARN: " + TWITTER_SECRET + " not set, Twitter auth will not be available...");
}
return success;
}

View File

@ -1,6 +1,5 @@
package org.libertybikes.auth.service.github;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
@ -51,7 +50,7 @@ public class GitHubCallback extends JwtAuth {
}
@GET
public Response getAuthURL(@Context HttpServletRequest request) throws IOException, URISyntaxException {
public Response getAuthURL(@Context HttpServletRequest request) throws URISyntaxException {
try {
String githubCode = request.getParameter("code");
String randomCode = (String) request.getSession().getAttribute("github");

View File

@ -0,0 +1,52 @@
package org.libertybikes.auth.service.twitter;
import java.net.URI;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.libertybikes.auth.service.ConfigBean;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;
@Path("/TwitterAuth")
@ApplicationScoped
public class TwitterAuth {
@Inject
ConfigBean config;
@GET
public Response getAuthURL(@Context HttpServletRequest request) {
ConfigurationBuilder c = new ConfigurationBuilder()
.setOAuthConsumerKey(config.twitter_key)
.setOAuthConsumerSecret(config.twitter_secret);
Twitter twitter = new TwitterFactory(c.build()).getInstance();
request.getSession().setAttribute("twitter", twitter);
try {
String callbackURL = config.authUrl + "/TwitterCallback";
RequestToken token = twitter.getOAuthRequestToken(callbackURL);
request.getSession().setAttribute("twitter_token", token);
// send the user to Twitter to be authenticated
String authorizationUrl = token.getAuthenticationURL();
return Response.temporaryRedirect(new URI(authorizationUrl)).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(500).build();
}
}
}

View File

@ -0,0 +1,75 @@
package org.libertybikes.auth.service.twitter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.libertybikes.auth.service.ConfigBean;
import org.libertybikes.auth.service.JwtAuth;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.ConfigurationBuilder;
@Path("/TwitterCallback")
@ApplicationScoped
public class TwitterCallback extends JwtAuth {
@Inject
ConfigBean config;
@GET
public Response getAuthURL(@Context HttpServletRequest request) throws URISyntaxException {
try {
Twitter twitter = (Twitter) request.getSession().getAttribute("twitter");
RequestToken reqToken = (RequestToken) request.getSession().getAttribute("twitter_token");
String verifier = request.getParameter("oauth_verifier");
if (verifier == null)
return fail();
request.getSession().removeAttribute("twitter_token");
AccessToken accessToken = twitter.getOAuthAccessToken(reqToken, verifier);
ConfigurationBuilder configBuilder = new ConfigurationBuilder()
.setOAuthConsumerKey(config.twitter_key)
.setOAuthConsumerSecret(config.twitter_secret)
.setOAuthAccessToken(accessToken.getToken())
.setOAuthAccessTokenSecret(accessToken.getTokenSecret())
.setIncludeEmailEnabled(true)
.setJSONStoreEnabled(true);
twitter = new TwitterFactory(configBuilder.build()).getInstance();
User user = twitter.verifyCredentials();
long twitterID = user.getId();
String name = user.getScreenName();
System.out.println("Got twitter ID=" + twitterID + " with name=" + name);
Map<String, String> claims = new HashMap<String, String>();
claims.put("valid", "true");
claims.put("id", "TWITTER:" + twitterID);
claims.put("upn", "" + name);
return Response.temporaryRedirect(new URI(config.frontendUrl + "/" + createJwt(claims))).build();
} catch (Exception e) {
e.printStackTrace();
return fail();
}
}
private Response fail() throws URISyntaxException {
return Response.temporaryRedirect(new URI(config.frontendUrl)).build();
}
}

View File

@ -21,6 +21,9 @@
<div class="form-item">
<button type="button" (click)="loginGithub()">Sign in with GitHub</button>
</div>
<div class="form-item">
<button type="button" (click)="loginTwitter()">Sign in with Twitter</button>
</div>
<h2 *ngIf="isFullDevice" class="section-header">or</h2>
<div *ngIf="isFullDevice" class="form-item">
<button type="button" (click)="hostRound()">Host Round</button>

View File

@ -76,6 +76,10 @@ export class LoginComponent implements OnInit, OnDestroy {
window.location.href = `${environment.API_URL_AUTH}/auth-service/GitHubAuth`;
}
loginTwitter() {
window.location.href = `${environment.API_URL_AUTH}/auth-service/TwitterAuth`;
}
async quickJoin() {
// First get an unstarted round ID
let roundID = await this.http.get(`${environment.API_URL_GAME_ROUND}/available`, { responseType: 'text' }).toPromise();

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry kind="src" output="build/classes/java/test" path="src/test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer">

View File

@ -10,7 +10,8 @@ public class Player {
public static enum DOMAIN {
BASIC,
GMAIL,
GITHUB;
GITHUB,
TWITTER;
@Override
public String toString() {