Java tutorial
/* * Copyright 2005-2014 Restlet * * The contents of this file are subject to the terms of one of the following * open source licenses: Apache 2.0 or LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL * 1.0 (the "Licenses"). You can select the license that you prefer but you may * not use this file except in compliance with one of these Licenses. * * You can obtain a copy of the Apache 2.0 license at * http://www.opensource.org/licenses/apache-2.0 * * You can obtain a copy of the LGPL 3.0 license at * http://www.opensource.org/licenses/lgpl-3.0 * * You can obtain a copy of the LGPL 2.1 license at * http://www.opensource.org/licenses/lgpl-2.1 * * You can obtain a copy of the CDDL 1.0 license at * http://www.opensource.org/licenses/cddl1 * * You can obtain a copy of the EPL 1.0 license at * http://www.opensource.org/licenses/eclipse-1.0 * * See the Licenses for the specific language governing permissions and * limitations under the Licenses. * * Alternatively, you can obtain a royalty free commercial license with less * limitations, transferable or non-transferable, directly at * http://www.restlet.com/products/restlet-framework * * Restlet is a registered trademark of Restlet */ package org.deviceconnect.android.localoauth; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.IntentFilter; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.os.Handler; import android.os.Looper; import android.support.v4.content.LocalBroadcastManager; import android.util.Base64; import org.deviceconnect.android.BuildConfig; import org.deviceconnect.android.localoauth.activity.ConfirmAuthActivity; import org.deviceconnect.android.localoauth.exception.AuthorizationException; import org.deviceconnect.android.localoauth.oauthserver.LoginPageServerResource; import org.deviceconnect.android.localoauth.oauthserver.SampleUser; import org.deviceconnect.android.localoauth.oauthserver.SampleUserManager; import org.deviceconnect.android.localoauth.oauthserver.db.LocalOAuthOpenHelper; import org.deviceconnect.android.localoauth.oauthserver.db.SQLiteClient; import org.deviceconnect.android.localoauth.oauthserver.db.SQLiteClientManager; import org.deviceconnect.android.localoauth.oauthserver.db.SQLiteToken; import org.deviceconnect.android.localoauth.oauthserver.db.SQLiteTokenManager; import org.deviceconnect.android.localoauth.temp.RedirectRepresentation; import org.deviceconnect.android.localoauth.temp.ResultRepresentation; import org.deviceconnect.android.logger.AndroidHandler; import org.json.JSONException; import org.restlet.Context; import org.restlet.Request; import org.restlet.Response; import org.restlet.data.ClientInfo; import org.restlet.data.Cookie; import org.restlet.data.Form; import org.restlet.data.Reference; import org.restlet.ext.oauth.AccessTokenServerResource; import org.restlet.ext.oauth.AuthPageServerResource; import org.restlet.ext.oauth.AuthorizationBaseServerResource; import org.restlet.ext.oauth.AuthorizationServerResource; import org.restlet.ext.oauth.OAuthException; import org.restlet.ext.oauth.PackageInfoOAuth; import org.restlet.ext.oauth.internal.Client; import org.restlet.ext.oauth.internal.Client.ClientType; import org.restlet.ext.oauth.internal.ClientManager; import org.restlet.ext.oauth.internal.Scope; import org.restlet.ext.oauth.internal.Token; import org.restlet.ext.oauth.internal.TokenManager; import org.restlet.representation.Representation; import org.restlet.representation.StringRepresentation; import org.restlet.util.Series; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; /** * Local OAuth API. */ public class LocalOAuth2Main { /** * ????????. */ public static final String ACTION_TOKEN_APPROVAL = "org.deviceconnect.android.localoauth.TOKEN_APPROVAL"; /** * ???????Thread ID????. */ public static final String EXTRA_THREAD_ID = "org.deviceconnect.android.localoauth.THREAD_ID"; /** * ?????????????. */ public static final String EXTRA_APPROVAL = "org.deviceconnect.android.localoauth.APPROVAL"; /** (RedirectURI). */ public static final String DUMMY_REDIRECT_URI = "dummyRedirectURI"; /** (OriginalRef). */ private static final String DUMMY_ORIGINAL_REF = "dummyOriginalRef"; /** (Reference). */ private static final String DUMMY_REFERENCE = "dummyReference"; /** (Scope). */ private static final String DUMMY_SCOPE1 = "scope1"; /** UserManager. */ private SampleUserManager mUserManager; /** ClientManager. */ private ClientManager mClientManager; /** TokenManager. */ private TokenManager mTokenManager; /** DBHelper. */ private LocalOAuthOpenHelper mDbHelper; /** Database. */ private SQLiteDatabase mDb; /** . */ private Logger sLogger = Logger.getLogger("org.deviceconnect.localoauth"); /** DBLock. */ private final Object mLockForDbAccess = new Object(); /** ???(??synchronized??). */ private List<ConfirmAuthRequest> mRequestQueue = new ArrayList<>(); /** ???Lock. */ private final Object mLockForRequestQueue = new Object(); private android.content.Context mContext; /** * . */ public LocalOAuth2Main(final android.content.Context context) { this(context, "localoauth.db"); } /** * . */ public LocalOAuth2Main(final android.content.Context context, final String dbName) { // Logger logger = sLogger; if (BuildConfig.DEBUG) { AndroidHandler handler = new AndroidHandler(logger.getName()); handler.setFormatter(new SimpleFormatter()); handler.setLevel(Level.ALL); logger.addHandler(handler); logger.setLevel(Level.ALL); } else { logger.setLevel(Level.OFF); } mContext = context; // DB?? mDbHelper = new LocalOAuthOpenHelper(context, dbName); mDb = mDbHelper.getWritableDatabase(); // ?? mUserManager = new SampleUserManager(); mClientManager = new SQLiteClientManager(mDb); mTokenManager = new SQLiteTokenManager(mDb); // addUserData(SampleUser.LOCALOAUTH_USER, SampleUser.LOCALOAUTH_PASS); register(context); } /** * (1)-2.LocalOAuth?. */ public void destroy() { unregister(mContext); // DB???? if (mDbHelper != null) { mDbHelper.close(); } mDb = null; mUserManager = null; mClientManager = null; mTokenManager = null; mDbHelper = null; mContext = null; } /** * SampleUserManager?. * @return SampleUserManager? */ public SampleUserManager getSampleUserManager() { return mUserManager; } /** * (2)?. * <p> * ????????. * </p> * @param packageInfo (Android)??????<br> * (Web)???????URL<br> * ????????ID<br> * @return ??(ID, )?<br> * null??? * @throws AuthorizationException Authorization. */ public ClientData createClient(final PackageInfoOAuth packageInfo) throws AuthorizationException { if (packageInfo == null) { throw new IllegalArgumentException("packageInfo is null."); } else if (packageInfo.getPackageName() == null) { throw new IllegalArgumentException("packageInfo.getPackageName() is null."); } else if (packageInfo.getPackageName().length() <= 0) { throw new IllegalArgumentException("packageInfo is empty."); } else if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } // ???????clientId?(DB????????) int clientCount = cleanupClient(); // ???????? if (clientCount >= LocalOAuth2Settings.CLIENT_MAX) { throw new AuthorizationException(AuthorizationException.CLIENT_COUNTS_IS_FULL); } // ClientData clientData; synchronized (mLockForDbAccess) { try { mDb.beginTransaction(); // ??ID?????? Client client = mClientManager.findByPackageInfo(packageInfo); if (client != null) { String clientId = client.getClientId(); removeTokenData(clientId); removeClientData(clientId); } // ????? client = addClientData(packageInfo); clientData = new ClientData(client.getClientId(), String.copyValueOf(client.getClientSecret())); mDb.setTransactionSuccessful(); } catch (SQLiteException e) { throw new RuntimeException(e); } finally { mDb.endTransaction(); } } return clientData; } /** * (5)???. * <p> * - Activity?process?????Device Connect Manager?????<br> * - Device Connect Manager???????(0)onBind()?Bind?<br> * - Messenger, Handler ?LocalOAuth???<br> * * - ????<br> * * - (a)?????(?) => * ?????/??Bind??Service?Message??<br> * * - (b)???????? => * ?????/??Bind??Service?Message??<br> * * - (c)?????? => ???????(Message???)<br> * </p> * @param params * @param listener (???????????) * @throws AuthorizationException Authorization. */ public void confirmPublishAccessToken(final ConfirmAuthParams params, final PublishAccessTokenListener listener) throws AuthorizationException { if (params == null) { throw new IllegalArgumentException("confirmAuthParams is null."); } else if (listener == null) { throw new IllegalArgumentException("publishAccessTokenListener is null."); } else if (params.getContext() == null) { throw new IllegalArgumentException("Context is null."); } else if (params.getApplicationName() == null || params.getApplicationName().isEmpty()) { throw new IllegalArgumentException("ApplicationName is null."); } else if (params.getClientId() == null || params.getClientId().isEmpty()) { throw new IllegalArgumentException("ClientId is null."); } else if (params.getScopes() == null || params.getScopes().length <= 0) { throw new IllegalArgumentException("Scope is null."); } else if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } synchronized (mLockForDbAccess) { // ID? Thread thread = Thread.currentThread(); final long threadId = thread.getId(); // ?(???????("ja_JP")???????) String locale = Locale.getDefault().getLanguage(); String[] splitLocales = locale.split("_"); if (splitLocales.length > 1) { locale = splitLocales[0]; } // ????devicePlugin.xml??????? Map<String, DevicePluginXmlProfile> supportProfiles = null; if (params.isForDevicePlugin()) { supportProfiles = DevicePluginXmlUtil.getSupportProfiles(params.getContext(), params.getContext().getPackageName()); } String[] scopes = params.getScopes(); String[] displayScopes = new String[scopes.length]; for (int i = 0; i < scopes.length; i++) { // ?????? displayScopes[i] = ScopeUtil.getDisplayScope(params.getContext(), scopes[i], locale, supportProfiles); } // ?? ConfirmAuthRequest request = new ConfirmAuthRequest(threadId, params, listener, displayScopes, params.isAutoFlag()); // ? enqueueRequest(request); // Activity??Bind????????? // Activity? if (mRequestQueue.size() <= 1) { startConfirmAuthActivity(pickupRequest()); } } } /** * 1?????. * @param t ??? * @return true???1?false????? */ private static boolean checkTime(final long t) { return 0 <= t && t <= (LocalOAuth2Settings.ACCESS_TOKEN_GRACE_TIME * LocalOAuth2Settings.MSEC); } /** * (7)??. * * @param accessToken ?? * @param scope ????????? * @param specialScopes ???????????scopes(null??) * @return ?? */ public CheckAccessTokenResult checkAccessToken(final String accessToken, final String scope, final String[] specialScopes) { if (scope == null) { throw new IllegalArgumentException("scope is null."); } // true: ??ID? // false: ??ID?? boolean isExistClientId = false; // true: ? / false: ?? boolean isExistAccessToken = false; // true: ? / false: ?? boolean isExistScope = false; // true: ? / false: ? boolean isNotExpired = false; // ??????? if (specialScopes != null && Arrays.asList(specialScopes).contains(scope)) { return new CheckAccessTokenResult(true, true, true, true); } // ??????? if (accessToken == null) { return new CheckAccessTokenResult(false, false, false, false); } synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { mDb.beginTransaction(); // ?? SQLiteToken token = (SQLiteToken) mTokenManager.findTokenByAccessToken(accessToken); if (token != null) { // ? isExistAccessToken = true; Scope[] scopes = token.getScope(); for (Scope s : scopes) { // token.scope?"*"????????????? if (BuildConfig.DEBUG && s.getScope().equals("*")) { isExistScope = true; // ? isNotExpired = true; // ? break; } if (s.getScope().equals(scope)) { isExistScope = true; // ? if (s.getExpirePeriod() == 0) { // ?0?????1?????? long t = System.currentTimeMillis() - token.getRegistrationDate(); if (checkTime(t) && token.isFirstAccess()) { isNotExpired = true; } } else if (s.getExpirePeriod() > 0) { // ?1????????????? isNotExpired = !s.isExpired(); } else { // ????????????? isNotExpired = false; } break; } } // ????ID???? if (mClientManager.findById(token.getClientId()) != null) { isExistClientId = true; } // ? if (token.isFirstAccess()) { token.dbUpdateTokenAccessTime(mDb); } } mDb.setTransactionSuccessful(); } catch (SQLiteException e) { throw new RuntimeException(e); } finally { mDb.endTransaction(); } } CheckAccessTokenResult result = new CheckAccessTokenResult(isExistClientId, isExistAccessToken, isExistScope, isNotExpired); if (!result.checkResult()) { sLogger.warning("checkAccessToken() - error."); sLogger.warning(" - isExistClientId: " + isExistClientId); sLogger.warning(" - isExistAccessToken: " + isExistAccessToken); sLogger.warning(" - isExistScope:" + isExistScope); sLogger.warning(" - isNotExpired:" + isNotExpired); sLogger.warning(" - accessToken:" + accessToken); sLogger.warning(" - scope:" + scope); } return result; } /** * (10)???. * * @param accessToken * @return not null: / null:???????????? */ public ClientPackageInfo findClientPackageInfoByAccessToken(final String accessToken) { if (accessToken == null) { throw new IllegalArgumentException("accessToken is null."); } else if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } ClientPackageInfo clientPackageInfo = null; synchronized (mLockForDbAccess) { try { SQLiteToken token = (SQLiteToken) mTokenManager.findTokenByAccessToken(accessToken); if (token != null) { String clientId = token.getClientId(); if (clientId != null) { Client client = mClientManager.findById(clientId); if (client != null) { clientPackageInfo = new ClientPackageInfo(client.getPackageInfo(), clientId); } } } } catch (Exception e) { throw new RuntimeException(e); } } return clientPackageInfo; } /** * (13)-1.??(startAccessTokenListActivity()). * @return not null: ?? / null: ?? */ public SQLiteToken[] getAccessTokens() { synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { // LocalOAuth??????? return (SQLiteToken[]) mTokenManager.findTokens(SampleUser.USERNAME); } catch (SQLiteException e) { throw new RuntimeException(e); } } } /** * ????. * <p> * ???????null?? * </p> * @param client * @return */ public SQLiteToken getAccessToken(final Client client) { synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { // LocalOAuth??????? return (SQLiteToken) mTokenManager.findToken(client, SampleUser.USERNAME); } catch (SQLiteException e) { throw new RuntimeException(e); } } } /** * (13)-2.??????????(startAccessTokenListActivity(). * * @param tokenId ID */ public void destroyAccessToken(final long tokenId) { synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { mDb.beginTransaction(); ((SQLiteTokenManager) mTokenManager).revokeToken(tokenId); mDb.setTransactionSuccessful(); } catch (SQLiteException e) { throw new RuntimeException(e); } finally { mDb.endTransaction(); } } } /** * (13)-3.DB?(startAccessTokenListActivity(). * */ public void destroyAllAccessToken() { synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { mDb.beginTransaction(); mTokenManager.revokeAllTokens(SampleUser.USERNAME); mDb.setTransactionSuccessful(); } catch (SQLiteException e) { throw new RuntimeException(e); } finally { mDb.endTransaction(); } } } /** * (13)-4.ID????(startAccessTokenListActivity()). * @param clientId ID * @return not null: / null: ?? */ public SQLiteClient findClientByClientId(final String clientId) { synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { // LocalOAuth??????? return (SQLiteClient) mClientManager.findById(clientId); } catch (SQLiteException e) { throw new RuntimeException(e); } } } /** * ???????clientId?(DB????????). * @return */ private int cleanupClient() { int clientCount; synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { throw new RuntimeException("Database is not opened."); } try { mDb.beginTransaction(); SQLiteClientManager mgr = (SQLiteClientManager) mClientManager; mgr.cleanupClient(LocalOAuth2Settings.CLIENT_CLEANUP_TIME); clientCount = mgr.countClients(); mDb.setTransactionSuccessful(); } catch (SQLiteException e) { throw new RuntimeException(e); } finally { mDb.endTransaction(); } } return clientCount; } /** * ???. * @param threadId ?ID * @param isApproval ????true?????false */ private void processApproval(final long threadId, final boolean isApproval) { // ?????????????? ConfirmAuthRequest request = dequeueRequest(threadId, false); if (request != null && !request.isDoneResponse()) { request.setDoneResponse(true); request.stopTimer(); PublishAccessTokenListener publishAccessTokenListener = request.getPublishAccessTokenListener(); ConfirmAuthParams params = request.getConfirmAuthParams(); if (isApproval) { AccessTokenData accessTokenData = null; AuthorizationException exception = null; synchronized (mLockForDbAccess) { if (!mDb.isOpen()) { exception = new AuthorizationException(AuthorizationException.SQLITE_ERROR); } else { try { mDb.beginTransaction(); // ?????? // (ID???????)? ((SQLiteTokenManager) mTokenManager).cleanup(); // accessTokenData = publishAccessToken(params); mDb.setTransactionSuccessful(); } catch (AuthorizationException e) { exception = e; } catch (SQLiteException e) { exception = new AuthorizationException(AuthorizationException.SQLITE_ERROR); } finally { mDb.endTransaction(); } } } if (exception == null) { // ??? callPublishAccessTokenListener(accessTokenData, publishAccessTokenListener); } else { // ????? callExceptionListener(exception, publishAccessTokenListener); } } else { // ???? callPublishAccessTokenListener(null, publishAccessTokenListener); } new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { // Activity????????????????? dequeueRequest(threadId, true); // ???????????Activity? final ConfirmAuthRequest nextRequest = pickupRequest(); if (nextRequest != null) { startConfirmAuthActivity(nextRequest); } } }, 2000); } } /** * ??. * * @param params ???? * @return * @throws AuthorizationException Authorization. */ private AccessTokenData publishAccessToken(final ConfirmAuthParams params) throws AuthorizationException { String clientId = params.getClientId(); Client client = mClientManager.findById(clientId); if (client != null) { // AuthSession??ID? RedirectRepresentation redirectRepresentation = callAuthorizationServerResource(client, true, null); if (redirectRepresentation != null) { String sessionId = redirectRepresentation.getOptions().get(RedirectRepresentation.SESSION_ID) .toString(); // ? ResultRepresentation result = callLoginPageServerResource(SampleUser.LOCALOAUTH_USER, SampleUser.LOCALOAUTH_PASS); if (result.getResult()) { RedirectRepresentation result3 = callAuthorizationServerResource(client, false, sessionId); if (result3 != null) { // ??xml????????? Map<String, DevicePluginXmlProfile> supportProfiles = null; if (params.isForDevicePlugin()) { supportProfiles = DevicePluginXmlUtil.getSupportProfiles(params.getContext(), params.getContext().getPackageName()); } // (Scope??????) String[] scopes = params.getScopes(); ArrayList<Scope> settingScopes = new ArrayList<>(); for (String scope : scopes) { // ??xml?????????(??) long expirePeriod = LocalOAuth2Settings.DEFAULT_TOKEN_EXPIRE_PERIOD; if (supportProfiles != null) { DevicePluginXmlProfile xmlProfile = supportProfiles.get(scope); if (xmlProfile != null) { expirePeriod = xmlProfile.getExpirePeriod(); } } Scope s = new Scope(scope, System.currentTimeMillis(), expirePeriod); settingScopes.add(s); } // ??? String applicationName = params.getApplicationName(); RedirectRepresentation result4 = callAuthPageServerResource(sessionId, settingScopes, applicationName); if (result4 != null) { Map<String, Object> options = result4.getOptions(); String authCode = (String) options.get(AuthPageServerResource.CODE); if (authCode != null) { // ? String accessToken = callAccessTokenServerResource(client, authCode, applicationName); // ? Token token = mTokenManager.findTokenByAccessToken(accessToken); // ? AccessTokenScope[] accessTokenScopes = scopesToAccessTokenScopes(token.getScope()); return new AccessTokenData(accessToken, token.getRegistrationDate(), accessTokenScopes); } } } } } } else { throw new AuthorizationException(AuthorizationException.CLIENT_NOT_FOUND); } return null; } /** * ???. * * @param accessTokenData * @param publishAccessTokenListener */ private void callPublishAccessTokenListener(final AccessTokenData accessTokenData, final PublishAccessTokenListener publishAccessTokenListener) { if (publishAccessTokenListener != null) { // ??? publishAccessTokenListener.onReceiveAccessToken(accessTokenData); } else { // ????????????? throw new RuntimeException("publishAccessTokenListener is null."); } } /** * ???. * * @param exception * @param publishAccessTokenListener */ private void callExceptionListener(final Exception exception, final PublishAccessTokenListener publishAccessTokenListener) { if (publishAccessTokenListener != null) { // ??? publishAccessTokenListener.onReceiveException(exception); } else { // ????????????? throw new RuntimeException("publishAccessTokenListener is null."); } } /** * AuthorizationServerResource. * * @param client * @param initialize ?(true???Context??) * @param sessionId ID(????ID???????null?) * @return not null: RedirectRepresentation?? / null: * @throws AuthorizationException Authorization. */ private RedirectRepresentation callAuthorizationServerResource(final Client client, final boolean initialize, final String sessionId) throws AuthorizationException { // AuthorizationServerResource?? if (initialize) { Context context = new Context(sLogger); AuthorizationServerResource.init(context); } // request, response? * Request request = new Request(); request.setOriginalRef(new Reference(DUMMY_ORIGINAL_REF)); Response response = new Response(request); request.setResourceRef(new Reference(DUMMY_REFERENCE)); // ID?????Request?? if (sessionId != null) { Series<Cookie> cookies = new Series<>(Cookie.class); cookies.add(AuthorizationBaseServerResource.ClientCookieID, sessionId); request.setCookies(cookies); } AuthorizationServerResource.init(request, response, mClientManager, mTokenManager); // Form?? Form paramsA = new Form(); paramsA.add(AuthorizationServerResource.CLIENT_ID, client.getClientId()); paramsA.add(AuthorizationServerResource.REDIR_URI, DUMMY_REDIRECT_URI); paramsA.add(AuthorizationServerResource.RESPONSE_TYPE, "code"); paramsA.add(AuthorizationServerResource.SCOPE, DUMMY_SCOPE1); // requestAuthorization? Representation representationA; try { representationA = AuthorizationServerResource.requestAuthorization(paramsA); } catch (OAuthException e) { throw new AuthorizationException(e); } // (?) if (representationA instanceof RedirectRepresentation) { return (RedirectRepresentation) representationA; } return null; } /** * LoginPageServerResource?. * * @param userId ID * @param password * @return (ResultRepresentation) */ private ResultRepresentation callLoginPageServerResource(final String userId, final String password) { // ????ID???? String sessionId = AuthorizationServerResource.getSessionId(); Series<Cookie> cookies = new Series<>(Cookie.class); cookies.add(AuthorizationBaseServerResource.ClientCookieID, sessionId); // (B)?? LoginPageServerResource.initResult(); Request request = new Request(); Reference requestReference = new Reference(DUMMY_ORIGINAL_REF); requestReference.addQueryParameter(LoginPageServerResource.USER_ID, userId); requestReference.addQueryParameter(LoginPageServerResource.PASSWORD, password); requestReference.addQueryParameter(LoginPageServerResource.CONTINUE, RedirectRepresentation.RedirectProc.requestAuthorization.toString()); // QueryParameter?????????? ArrayList<String> userIds = new ArrayList<>(); userIds.add(userId); ArrayList<String> passwords = new ArrayList<>(); passwords.add(password); ArrayList<String> continues = new ArrayList<>(); continues.add(RedirectRepresentation.RedirectProc.requestAuthorization.toString()); LoginPageServerResource.getQuery().put(LoginPageServerResource.USER_ID, userIds); LoginPageServerResource.getQuery().put(LoginPageServerResource.PASSWORD, passwords); LoginPageServerResource.getQuery().put(LoginPageServerResource.CONTINUE, continues); request.setCookies(cookies); request.setOriginalRef(requestReference); request.setResourceRef(requestReference); Response response = new Response(request); LoginPageServerResource.init(request, response); ResultRepresentation resultRepresentation; try { resultRepresentation = (ResultRepresentation) LoginPageServerResource.getPage(this); } catch (OAuthException e) { resultRepresentation = new ResultRepresentation(); resultRepresentation.setResult(false); resultRepresentation.setError(e.getMessage(), e.getErrorDescription()); } return resultRepresentation; } /** * AuthPageServerResource?. * * @param sessionId ID * @param scopes * @param applicationName ?? * @return (RedirectRepresentation) */ private RedirectRepresentation callAuthPageServerResource(final String sessionId, final ArrayList<Scope> scopes, final String applicationName) { Series<Cookie> cookies = new Series<>(Cookie.class); cookies.add(AuthorizationBaseServerResource.ClientCookieID, sessionId); // scopes???? ArrayList<String> strScopes = ScopeUtil.scopesToStrings(scopes); ArrayList<String> actions = new ArrayList<>(); actions.add(AuthPageServerResource.ACTION_ACCEPT); ArrayList<String> applicationNames = new ArrayList<>(); applicationNames.add(applicationName); AuthPageServerResource.getQuery().put(AuthPageServerResource.SCOPE, strScopes); AuthPageServerResource.getQuery().put(AuthPageServerResource.GRANTED_SCOPE, new ArrayList<String>()); AuthPageServerResource.getQuery().put(AuthPageServerResource.ACTION, actions); AuthPageServerResource.getQuery().put(AuthPageServerResource.APPLICATION_NAME, applicationNames); Request request = new Request(); request.setCookies(cookies); Response response = new Response(request); AuthPageServerResource.init(request, response); RedirectRepresentation redirectRepresentation = null; try { Representation representation = AuthPageServerResource.showPage(); if (representation != null) { if (representation instanceof RedirectRepresentation) { redirectRepresentation = (RedirectRepresentation) representation; } } } catch (OAuthException e) { e.printStackTrace(); } return redirectRepresentation; } /** * ??????. * * @param client * @param authCode ??(TokenManager.sessions???) * @param applicationName ?? * @return not null: / null: ? */ private String callAccessTokenServerResource(final Client client, final String authCode, final String applicationName) { Request request = new Request(); ClientInfo clientInfo = new ClientInfo(); org.restlet.security.User user = new org.restlet.security.User(client.getClientId()); clientInfo.setUser(user); request.setClientInfo(clientInfo); Response response = new Response(request); AccessTokenServerResource.init(request, response); // (???base64?) String base64ApplicationName = Base64.encodeToString(applicationName.getBytes(), Base64.URL_SAFE | Base64.NO_WRAP); StringRepresentation input = new StringRepresentation("grant_type=authorization_code&code=" + authCode + "&" + AccessTokenServerResource.REDIR_URI + "=" + DUMMY_REDIRECT_URI + "&" + AccessTokenServerResource.APPLICATION_NAME + "=" + base64ApplicationName); try { ResultRepresentation resultRepresentation = (ResultRepresentation) AccessTokenServerResource .requestToken(input); if (resultRepresentation.getResult()) { return resultRepresentation.getText(); } } catch (JSONException | OAuthException e) { e.printStackTrace(); } return null; } /** * . * * @param user ID * @param pass */ private void addUserData(final String user, final String pass) { mUserManager.addUser(user).setPassword(pass.toCharArray()); } /** * . * * @param packageInfo ?? * @return */ private Client addClientData(final PackageInfoOAuth packageInfo) { String[] redirectURIs = { DUMMY_REDIRECT_URI }; Map<String, Object> params = new HashMap<>(); return mClientManager.createClient(packageInfo, ClientType.CONFIDENTIAL, redirectURIs, params); } /** * . * * @param clientId ID */ private void removeClientData(final String clientId) { Client client = mClientManager.findById(clientId); if (client != null) { mClientManager.deleteClient(clientId); } } /** * ????????. * @param clientId */ private void removeTokenData(final String clientId) { Client client = mClientManager.findById(clientId); if (client != null) { mTokenManager.revokeToken(client); } } /** * ?????. * * @param request */ private void enqueueRequest(final ConfirmAuthRequest request) { synchronized (mLockForRequestQueue) { mRequestQueue.add(request); } } /** * ???????. * * @return not null: ??? / null: ??? */ private ConfirmAuthRequest pickupRequest() { synchronized (mLockForRequestQueue) { while (mRequestQueue.size() > 0) { ConfirmAuthRequest request = mRequestQueue.get(0); if (System.currentTimeMillis() - request.getRequestTime() < 60 * 1000) { return request; } mRequestQueue.remove(0); } } return null; } /** * threadId????????(?????). * * @param threadId ??ID * @param isDeleteRequest true: ID????????? / false: ??? * @return not null: ??? / null: ???(???threadId?????????) */ private ConfirmAuthRequest dequeueRequest(final long threadId, final boolean isDeleteRequest) { ConfirmAuthRequest request = null; synchronized (mLockForRequestQueue) { // ID??? int requestCount = mRequestQueue.size(); for (int i = 0; i < requestCount; i++) { ConfirmAuthRequest req = mRequestQueue.get(i); if (req.getThreadId() == threadId) { if (isDeleteRequest) { // ID??????? request = mRequestQueue.remove(i); } else { // ID??? request = mRequestQueue.get(i); } break; } } } return request; } /** * Scope[]?AccessTokenScope[]?????. * @param scopes Scope[]? * @return AccessTokenScope[]? */ private AccessTokenScope[] scopesToAccessTokenScopes(final Scope[] scopes) { if (scopes != null && scopes.length > 0) { AccessTokenScope[] accessTokenScopes = new AccessTokenScope[scopes.length]; for (int i = 0; i < scopes.length; i++) { Scope scope = scopes[i]; accessTokenScopes[i] = new AccessTokenScope(scope.getScope(), scope.getExpirePeriod()); } return accessTokenScopes; } return null; } /** * ??????. * @param request */ public void startConfirmAuthActivity(final ConfirmAuthRequest request) { if (request == null) { return; } android.content.Context context = request.getConfirmAuthParams().getContext(); long threadId = request.getThreadId(); ConfirmAuthParams params = request.getConfirmAuthParams(); String[] displayScopes = request.getDisplayScopes(); // Activity(??????ApprovalHandler??) Intent intent = new Intent(); intent.setClass(params.getContext(), ConfirmAuthActivity.class); intent.putExtra(ConfirmAuthActivity.EXTRA_THREAD_ID, threadId); if (params.getServiceId() != null) { intent.putExtra(ConfirmAuthActivity.EXTRA_SERVICE_ID, params.getServiceId()); } intent.putExtra(ConfirmAuthActivity.EXTRA_APPLICATION_NAME, params.getApplicationName()); intent.putExtra(ConfirmAuthActivity.EXTRA_SCOPES, params.getScopes()); intent.putExtra(ConfirmAuthActivity.EXTRA_DISPLAY_SCOPES, displayScopes); intent.putExtra(ConfirmAuthActivity.EXTRA_REQUEST_TIME, request.getRequestTime()); intent.putExtra(ConfirmAuthActivity.EXTRA_IS_FOR_DEVICEPLUGIN, params.isForDevicePlugin()); if (!params.isForDevicePlugin()) { intent.putExtra(ConfirmAuthActivity.EXTRA_PACKAGE_NAME, context.getPackageName()); intent.putExtra(ConfirmAuthActivity.EXTRA_KEYWORD, params.getKeyword()); } intent.putExtra(ConfirmAuthActivity.EXTRA_AUTO_FLAG, request.isAutoFlag()); intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); request.startTimer(new ConfirmAuthRequest.OnTimeoutCallback() { @Override public void onTimeout() { processApproval(request.getThreadId(), false); } }); } /** * ??????????LocalBroadcastReceiver???. * * @param context ? */ private void register(android.content.Context context) { IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_TOKEN_APPROVAL); LocalBroadcastManager.getInstance(context).registerReceiver(mBroadcastReceiver, filter); } /** * ??????????LocalBroadcastReceiver???. * * @param context ? */ private void unregister(android.content.Context context) { LocalBroadcastManager.getInstance(context).unregisterReceiver(mBroadcastReceiver); } /** * ??????????LocalBroadcastReceiver. */ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(android.content.Context context, Intent intent) { if (intent == null) { return; } String action = intent.getAction(); if (ACTION_TOKEN_APPROVAL.equals(action)) { long threadId = intent.getLongExtra(EXTRA_THREAD_ID, -1); boolean isApproval = intent.getBooleanExtra(EXTRA_APPROVAL, false); processApproval(threadId, isApproval); } } }; }