Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/chenjianjx/srb4j
Browse files Browse the repository at this point in the history
  • Loading branch information
shaunyip@outlook.com committed Jun 1, 2016
2 parents f9b3d94 + 6f26b61 commit 7529a71
Show file tree
Hide file tree
Showing 34 changed files with 1,089 additions and 524 deletions.
382 changes: 225 additions & 157 deletions README.md

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions documents/test-cases/client-test-cases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Client-Side Test Cases


## Authentication

### Registration

### Local Login

### Social Login

* Google
* Facebook

### Invoke Business

* Try Protected Resource without Logging in
* Expectation: User redirected to login UI

* Try Protected Resource after Logging in
16 changes: 16 additions & 0 deletions documents/userguide/social-integration/facebook_desktop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Facebook Login for Desktop Clients

Note: A Desktop is a system that doesn't have facebook's SDK support and is able to launch a web view, such as Java GUI, .NET GUI and so on.

You will obtain Facebook's OAuth2 code according to [Manually Build a Login Flow](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow) and send it to http://your-backend/token/new/social/by-auth-code/facebook/desktop .


# Steps
* [Create a facebook APP](https://developers.facebook.com/apps/) if you haven't got one.
* Add "https://www.facebook.com/connect/login_success.html" to the APP's "Valid OAuth redirect URIs".
* Follow [the manual flow](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow), and check out our sample code.
* Make a simple button
* See [facebookCodeLoginBtn.addActionListener()](https://github.com/chenjianjx/srb4j-desktop-client/blob/master/src/main/java/org/srb4j/desktopclient/view/MainForm.java). You will construct the facebook auth url, launch it with a web view inside your client application.
* See [WebEngineChangeListener.changed()](https://github.com/chenjianjx/srb4j-desktop-client/blob/master/src/main/java/org/srb4j/desktopclient/view/auth/SocialLoginBrowser.java). You will monitor the browser's URL until you get the auth code, and then send the code to srb4j's back end.
* [getEmailFromCode](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoFacebookAuthHelper.java) is the server-side code. You don't have to change it, but you will set "facebookClientId" and "facebookClientId" on app.properties.

12 changes: 12 additions & 0 deletions documents/userguide/social-integration/facebook_html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Facebook Login for Html Clients

You will obtain Facebook's OAuth2 code according to [Manually Build a Login Flow](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow) and send it to http://your-backend/token/new/social/by-auth-code/facebook/web

# Steps

* [Create a facebook APP](https://developers.facebook.com/apps/) if you haven't got one.
* Follow [the manual flow](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow), and check out our sample code.
* Make a [button](https://github.com/chenjianjx/srb4j-html-client/blob/master/dashboard.html)
* See [$scope.facebookLogin()](https://github.com/chenjianjx/srb4j-html-client/blob/master/home.js) to go to facebook dialog page. You will create a facebook url inside your html client, and add it to "Valid OAuth redirect URIs" on [facebook's app center](https://developers.facebook.com/apps/).
* After the user has signed in, he will land onto the redirected_uri page inside your html client. Extract the code from current URL and send it to srb4j's backend. See [SocialLoginByFbCodeController](https://github.com/chenjianjx/srb4j-html-client/blob/master/home.js)
* [getEmailFromCode](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoFacebookAuthHelper.java) is the server-side code. You don't have to change it, but you will set "facebookClientId" and "facebookClientId" on app.properties.
19 changes: 19 additions & 0 deletions documents/userguide/social-integration/facebook_mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Facebook Login for Mobile Clients

You will integrate Facebook's Android/IOS SDK, get the access token after user has signed-in, and send the token to http://your-backend/token/new/social/by-token/google/mobile


# Steps for Android
1. Integrate Facebook SDK according to https://developers.facebook.com/quickstarts/ and https://developers.facebook.com/docs/android/getting-started/
2. Integrate facebook sign-in according to [this tutorial](http://code.tutsplus.com/tutorials/quick-tip-add-facebook-login-to-your-android-app--cms-23837) and our sample code:
* You can use a simple button instead of the button provided by the SDK. See [facebook_sign_in_button](https://github.com/chenjianjx/Srb4jAndroidClient/blob/master/app/src/main/res/layout/content_dashboard.xml)
* See [DashboardActivity](https://github.com/chenjianjx/Srb4jAndroidClient/blob/master/app/src/main/java/org/srb4j/androidclient/DashboardActivity.java) for front end sample code
3. Backend code is [getEmailFromToken](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoFacebookAuthHelper.java). You don't need to make any change, but you will set "facebookClientId" and "facebookClientId" on app.properties.


# Steps for IOS

It's similar with the Android one. Can anybody help write the steps for IOS ?



13 changes: 13 additions & 0 deletions documents/userguide/social-integration/google_desktop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Google Login for Desktop Clients

Note: A Desktop is a system that doesn't have google's SDK support and is able to launch a web view, such as Java GUI, .NET GUI and so on.

You will follow [Google's Installed Applications](https://developers.google.com/identity/protocols/OAuth2InstalledApp) flow, get the auth code and send it to http://your-backend/token/new/social/by-auth-code/google/desktop .


# Steps
1. [Create a Google Client ID](https://console.developers.google.com/apis/credentials). Pick "Other" on "Application type" selection.
2. See [googleCodeLoginBtn.addActionListener()](https://github.com/chenjianjx/srb4j-desktop-client/blob/master/src/main/java/org/srb4j/desktopclient/view/MainForm.java). You will construct the facebook auth url, launch it with a web view inside your client application.
3. See [WebEngineChangeListener.changed()](https://github.com/chenjianjx/srb4j-desktop-client/blob/master/src/main/java/org/srb4j/desktopclient/view/auth/SocialLoginBrowser.java). You will monitor the browser's URL until you get the auth code, and then send the code to srb4j's back end.
4. The back end's code is [getEmailFromCode](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoFacebookAuthHelper.java). You don't need to change it, but you will set "googleClientId" and "googleClientSecret" on app.properties.

8 changes: 8 additions & 0 deletions documents/userguide/social-integration/google_html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Google Login for Html Clients

You will obtain Google's OAuth2 code according to [Google Sign-in's Server Side Flow](https://developers.google.com/identity/sign-in/web/server-side-flow#implementing_the_one-time-code_flow) and send the code to http://your-backend/token/new/social/by-auth-code/google/web

# Notes

* You can refer to [index.html](https://github.com/chenjianjx/srb4j-html-client/blob/master/index.html) and [SocialLoginGoogleController](https://github.com/chenjianjx/srb4j-html-client/blob/master/home.js) for client-side code
* [getEmailFromCode](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoGoogleAuthHelper.java) is the server-side code. You don't have to change it, but you will set "googleWebClientId" and "googleWebClientSecret" on app.properties.
28 changes: 28 additions & 0 deletions documents/userguide/social-integration/google_mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Google Login for Mobile Clients

You will integrate Google's Android/IOS SDK, get the id token after user has signed-in, and send the token to http://your-backend/token/new/social/by-token/google/mobile


# Steps for Android
1. [Sign your APP](https://developer.android.com/studio/publish/app-signing.html) first. You will get a key store file.
2. run ````keytool -exportcert -keystore the-keys-store.jks -list -v```` to get the sha-1 fingerprint
3. [Get the configuration file](https://developers.google.com/identity/sign-in/android/start-integrating#get-config). You will input the sha-1 fingerprint obtained during previous steps.
4. [Go on with the integration] (https://developers.google.com/identity/sign-in/android/start-integrating)
* You can use a simple button instead of the button provided by the SDK. See [google_sign_in_button](https://github.com/chenjianjx/Srb4jAndroidClient/blob/master/app/src/main/res/layout/content_dashboard.xml)
* See [DashboardActivity](https://github.com/chenjianjx/Srb4jAndroidClient/blob/master/app/src/main/java/org/srb4j/androidclient/DashboardActivity.java) for front end sample code
6. Backend code is [getEmailFromToken](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoGoogleAuthHelper.java). You don't have to make any change, but you will set "googleWebClientId" and "googleWebClientSecret" on app.properties.(Yes, we use web client id on the back end even it's for mobile sign-in, as Google says so).


## Not Working during Development?
The previous setup is for the release version of your Android APP. You will encounter "unknown status code: 12501" (or 12500) errors during development, because you are running a debug version.

To get your debug version running,
* Find out the sha-1 fingerprint for debug. ````keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore````, input “android” as the password.
* Go to the google developer’s console, create another clientId under the same project, input the debug fingerprint for it, and update the client-id and fingerprint on the google-services.json accordingly. See the comments in the [sample code](https://github.com/chenjianjx/Srb4jAndroidClient/blob/master/app/google-services.json).

# Steps for IOS

It's similar with the Android one. Can anybody help write the steps for IOS ?



5 changes: 5 additions & 0 deletions documents/userguide/social-integration/new_site.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Integrate New Social Sites

* Do what you have to do according to the social site's guide
* Add a source to [User] class(https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/biz/user/User.java)
* Create a class to handle auth code or acess token. This class must implement [FoSocialSiteAuthHelper](https://github.com/chenjianjx/srb4jfullsample/blob/master/impl/src/main/java/com/github/chenjianjx/srb4jfullsample/impl/fo/auth/socialsite/FoSocialSiteAuthHelper.java) and register the class in FoSocialSiteAuthHelper.Factory
15 changes: 11 additions & 4 deletions src/main/resources/archetype-resources/demo-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,7 @@
</dependency>


<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>


<dependency>
<groupId>io.swagger</groupId>
Expand All @@ -80,6 +77,16 @@
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
</dependency>

<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package ${package}.democlient.bo.portal;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.Response;

import org.junit.Assert;
import org.junit.Test;
import ${package}.democlient.util.DemoClientConstants;
import ${package}.democlient.util.DemoClientUtils;

/**
*
Expand All @@ -18,7 +18,7 @@
public class DemoClientBoPortalTest {

private static final String BBSADMIN_EMAIL = "bbsadmin@nonexist.com";
private static Client mockClient = ClientBuilder.newClient();
private static Client mockClient = DemoClientUtils.createRestClient();

@Test
public void loginFormTest() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
*/
public class DemoClientFoAuthTest {

private static Client restClient = ClientBuilder.newClient();
private static Client restClient = DemoClientUtils.createRestClient();

@Test
public void testProtectedResourceWithoutLogin() {
Response restResponse = restClient.target(BACKEND_FO_REST_URL)
.path(DemoClientConstants.PROCTED_RESOURCE_URL)
.request(MediaType.APPLICATION_JSON_TYPE).get();
Assert.assertEquals(400, restResponse.getStatus());
Assert.assertNotNull(restResponse.getHeaderString("www-authenticate"));
Assert.assertNotNull(restResponse.getHeaderString("WWW-Authenticate"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.junit.Assert;

import ${package}.democlient.util.DemoClientConstants;
import ${package}.democlient.util.DemoClientUtils;
import ${package}.restclient.model.GenRandomLoginCodeRequest;
import com.github.scribejava.apis.GoogleApi20;
import com.github.scribejava.apis.google.GoogleToken;
Expand All @@ -40,18 +41,10 @@
*
*/
public class DemoClientFoAuthUiMain {
private static Client restClient = ClientBuilder.newClient();
private static Client restClient = DemoClientUtils.createRestClient();

public static void main(String[] args) throws Exception {

facebookLoginByTokenFlow();
googleLoginByTokenFlow();

/**
* for social login by code, see <a
* href="https://github.com/chenjianjx/srb4j-desktop-client">here</a>
*/

randomCodeLoginFlow();

}
Expand Down Expand Up @@ -114,141 +107,4 @@ public static void randomCodeLoginFlow() throws IOException {

}

private static void googleLoginByTokenFlow() throws IOException {
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(
System.in));

System.out.print("Please input your google client id: \n >>");
String googleClientId = consoleInput.readLine();

System.out.print("Please input your google client screct: \r\n >>");
String googleClientSecret = consoleInput.readLine();

final OAuth20Service service = new ServiceBuilder()
.apiKey(googleClientId).apiSecret(googleClientSecret)
.scope("email")
// replace with desired scope
.callback("urn:ietf:wg:oauth:2.0:oob")
.build(GoogleApi20.instance());

final String authorizationUrl = service.getAuthorizationUrl();
System.out
.println("Please copy the following url and visit it on your browser. Copy the code on the page and paste it here");
System.out.println(authorizationUrl);
System.out.print(">>");
final Verifier verifier = new Verifier(consoleInput.readLine());
System.out.println();

final GoogleToken accessToken = (GoogleToken) service
.getAccessToken(verifier);
String googleIdToken = accessToken.getOpenIdToken();
System.out.println("the idToken is: " + googleIdToken);

WebTarget target = restClient.target(BACKEND_FO_REST_URL)
.path(DemoClientConstants.SOCIAL_LOGIN_BY_TOKEN_URL_PREFIX
+ "google");
Form form = new Form();
form.param("grant_type", "password");
form.param("username", googleIdToken);
form.param("password", "anything");
form.param("long_session", "false");

Response restResponse = target.request(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.form(form));

DemoClientFoAuthTokenResponse clientResponse = DemoClientFoAuthTokenResponse
.parseRestResponse(restResponse);

DemoClientFoAuthTest.assertAuthResponseSuccessful(clientResponse);

}

private static void facebookLoginByTokenFlow() throws IOException {
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(
System.in));

System.out.print("Please input your facebook app id: \n >>");
String clientId = consoleInput.readLine();

System.out.print("Please input your facebook app screct: \r\n >>");
String clientSecret = consoleInput.readLine();

final OAuth20Service service = new ServiceBuilder()
.apiKey(clientId)
.apiSecret(clientSecret)
.scope("email")
// replace with desired scope
.callback("https://www.facebook.com/connect/login_success.html")
.build(new DemoClientFacebookApi());

final String authorizationUrl = service.getAuthorizationUrl();
System.out
.println("Now open your browser and show the 'inspect' window to monitor the url redirection");
System.out
.println("Copy the following url and visit it on your browser. And then extract the code accoring to\n https://raw.githubusercontent.com/chenjianjx/srb4j/master/src/main/resources/archetype-resources/demo-client/doc/fo/extract-facebook-code.png: ");
System.out.println(authorizationUrl);
System.out.print(">>");
Verifier verifier = new Verifier(consoleInput.readLine());
Token accessToken = service.getAccessToken(verifier);

System.out.println("the access token is: " + accessToken.getToken());

WebTarget target = restClient.target(BACKEND_FO_REST_URL).path(
DemoClientConstants.SOCIAL_LOGIN_BY_TOKEN_URL_PREFIX
+ "facebook");
Form form = new Form();
form.param("grant_type", "password");
form.param("username", accessToken.getToken());
form.param("password", "anything");
form.param("long_session", "false");

Response restResponse = target.request(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE)
.post(Entity.form(form));

DemoClientFoAuthTokenResponse clientResponse = DemoClientFoAuthTokenResponse
.parseRestResponse(restResponse);

DemoClientFoAuthTest.assertAuthResponseSuccessful(clientResponse);

}

public static class DemoClientFacebookApi extends DefaultApi20 {

private static final String AUTHORIZE_URL = "https://www.facebook.com/v2.5/dialog/oauth?client_id=%s&redirect_uri=%s";

@Override
public String getAccessTokenEndpoint() {
return "https://graph.facebook.com/v2.5/oauth/access_token";
}

@Override
public String getAuthorizationUrl(final OAuthConfig config) {
Preconditions
.checkValidUrl(config.getCallback(),
"Must provide a valid url as callback. Facebook does not support OOB");
final StringBuilder sb = new StringBuilder(String.format(
AUTHORIZE_URL, config.getApiKey(),
OAuthEncoder.encode(config.getCallback())));
if (config.hasScope()) {
sb.append('&').append(OAuthConstants.SCOPE).append('=')
.append(OAuthEncoder.encode(config.getScope()));
}

final String state = config.getState();
if (state != null) {
sb.append('&').append(OAuthConstants.STATE).append('=')
.append(OAuthEncoder.encode(state));
}
return sb.toString();
}

@Override
public AccessTokenExtractor getAccessTokenExtractor() {
return new JsonTokenExtractor();
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private static <T> DemoClientFoBizResponse<T> doParseResponse(

if (OAUTH2_HTTP_ERROR_CODES.contains(restResponse.getStatus())) {
String wwwAuthHeader = restResponse
.getHeaderString("www-authenticate");
.getHeaderString("WWW-Authenticate");
Map<String, String> headerValues = decodeOAuthHeader(wwwAuthHeader);
result.oauth2Error = new ErrorResult();
result.oauth2Error.setError(headerValues.get("error"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
public class DemoClientFoBizTest {
private static final String BIZ_RESOURCE_URL = "/bbs/posts/new";
private Client restClient = ClientBuilder.newClient();
private Client restClient = DemoClientUtils.createRestClient();

@Test
public void bizTest() {
Expand Down

0 comments on commit 7529a71

Please sign in to comment.