protected void startOAuth() { // Use already logged in accounts if not disabled in this activity and not already showing this // fragment. if (authType != AUTH_TYPE_APP && !getIntent().getBooleanExtra(EXTRA_DISABLE_ACCOUNT_CHOOSING, false) && getSupportFragmentManager().findFragmentByTag(CHOOSE_AUTH_TAG) == null) { Map<String, BoxAuthenticationInfo> map = BoxAuthentication.getInstance().getStoredAuthInfo(this); if (SdkUtils.isEmptyString(getIntent().getStringExtra(EXTRA_USER_ID_RESTRICTION)) && map != null && map.size() > 0) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace( R.id.oauth_container, ChooseAuthenticationFragment.createAuthenticationActivity(this), CHOOSE_AUTH_TAG); transaction.addToBackStack(CHOOSE_AUTH_TAG); transaction.commit(); } } switch (authType) { case AUTH_TYPE_APP: Intent intent = getBoxAuthApp(); if (intent != null) { intent.putExtra(BoxConstants.KEY_CLIENT_ID, mClientId); intent.putExtra(BoxConstants.KEY_REDIRECT_URL, mRedirectUrl); if (!SdkUtils.isEmptyString(getIntent().getStringExtra(EXTRA_USER_ID_RESTRICTION))) { intent.putExtra( EXTRA_USER_ID_RESTRICTION, getIntent().getStringExtra(EXTRA_USER_ID_RESTRICTION)); } startActivityForResult(intent, REQUEST_BOX_APP_FOR_AUTH_CODE); break; } case AUTH_TYPE_WEBVIEW: showSpinner(); this.oauthView = createOAuthView(); this.oauthClient = createOAuthWebViewClient(oauthView.getStateString()); oauthClient.setOnPageFinishedListener(this); oauthView.setWebViewClient(oauthClient); if (mSession.getBoxAccountEmail() != null) { oauthView.setBoxAccountEmail(mSession.getBoxAccountEmail()); } oauthView.authenticate(mClientId, mRedirectUrl); break; default: } }
public BoxSession send() throws BoxException { synchronized (mSession) { if (mSession.getUser() == null) { if (mSession.getAuthInfo() != null && !SdkUtils.isBlank(mSession.getAuthInfo().accessToken())) { // if we have an access token, but no user try to repair by making the call to user // endpoint. try { // TODO: show some ui while requestion user info BoxApiUser apiUser = new BoxApiUser(mSession); BoxUser user = apiUser.getCurrentUserInfoRequest().send(); mSession.setUserId(user.getId()); mSession.getAuthInfo().setUser(user); mSession.onAuthCreated(mSession.getAuthInfo()); return mSession; } catch (BoxException e) { BoxLogUtils.e("BoxSession", "Unable to repair user", e); if (e instanceof BoxException.RefreshFailure && ((BoxException.RefreshFailure) e).isErrorFatal()) { // if the refresh failure is unrecoverable have the user login again. toastString(mSession.getApplicationContext(), R.string.boxsdk_error_fatal_refresh); } else if (e.getErrorType() == BoxException.ErrorType.TERMS_OF_SERVICE_REQUIRED) { toastString( mSession.getApplicationContext(), R.string.boxsdk_error_terms_of_service); } else { mSession.onAuthFailure(null, e); throw e; } } // at this point we were unable to repair. } BoxAuthentication.getInstance().addListener(this); launchAuthUI(); return mSession; } else { BoxAuthentication.BoxAuthenticationInfo info = BoxAuthentication.getInstance() .getAuthInfo(mSession.getUserId(), mSession.getApplicationContext()); if (info != null) { BoxAuthentication.BoxAuthenticationInfo.cloneInfo(mSession.mAuthInfo, info); mSession.onAuthCreated(mSession.getAuthInfo()); } else { // Fail to get information of current user. current use no longer valid. mSession.mAuthInfo.setUser(null); launchAuthUI(); } } return mSession; } }
@Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION) && SdkUtils.isInternetAvailable(context)) { // if we are not showing a web page then redo the authentication. if ((oauthView != null) && (oauthView.getUrl() != null) && !oauthView.getUrl().startsWith("http")) { startOAuth(); } } }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (RESULT_OK == resultCode && REQUEST_BOX_APP_FOR_AUTH_CODE == requestCode) { String userId = data.getStringExtra(USER_ID); String authCode = data.getStringExtra(AUTH_CODE); if (SdkUtils.isBlank(authCode) && !SdkUtils.isBlank(userId)) { Map<String, BoxAuthenticationInfo> authenticatedMap = BoxAuthentication.getInstance().getStoredAuthInfo(this); BoxAuthenticationInfo info = authenticatedMap.get(userId); if (info != null) { onAuthenticationChosen(info); } else { onAuthFailure(new AuthFailure(AuthFailure.TYPE_USER_INTERACTION, "")); } } else if (!SdkUtils.isBlank(authCode)) { startMakingOAuthAPICall(authCode, null); } } else if (resultCode == RESULT_CANCELED) { finish(); } }
/** * Create a BoxSession using a specific box clientId, secret, and redirectUrl. This constructor is * not necessary unless an application uses multiple api keys. Note: When setting the userId to * null ui will be shown to ask which user to authenticate as if at least one user is logged in. * If no user has been stored will show login ui. * * @param context current context. * @param clientId the developer's client id to access the box api. * @param clientSecret the developer's secret used to interpret the response coming from Box. * @param redirectUrl the developer's redirect url to use for authenticating via Box. * @param userId user id to login as or null to login as a new user. */ public BoxSession( Context context, String userId, String clientId, String clientSecret, String redirectUrl) { mClientId = clientId; mClientSecret = clientSecret; mClientRedirectUrl = redirectUrl; if (SdkUtils.isEmptyString(mClientId) || SdkUtils.isEmptyString(mClientSecret)) { throw new RuntimeException( "Session must have a valid client id and client secret specified."); } mApplicationContext = context.getApplicationContext(); if (!SdkUtils.isEmptyString(userId)) { mAuthInfo = BoxAuthentication.getInstance().getAuthInfo(userId, context); mUserId = userId; } if (mAuthInfo == null) { mUserId = userId; mAuthInfo = new BoxAuthentication.BoxAuthenticationInfo(); } mAuthInfo.setClientId(mClientId); setupSession(); }
/** * This is an advanced constructor that can be used when implementing an authentication flow that * differs from the default oauth 2 flow. * * @param context current context. * @param authInfo authentication information that should be used. (Must at the minimum provide an * access token). * @param refreshProvider the refresh provider to use when the access token expires and needs to * be refreshed. */ public BoxSession( Context context, BoxAuthentication.BoxAuthenticationInfo authInfo, BoxAuthentication.AuthenticationRefreshProvider refreshProvider) { mApplicationContext = context.getApplicationContext(); mAuthInfo = authInfo; mRefreshProvider = refreshProvider; if (authInfo.getUser() != null) { if (!SdkUtils.isBlank(authInfo.getUser().getId())) { mUserId = authInfo.getUser().getId(); } } }
/** * Create intent to launch OAuthActivity using information from the given session. * * @param context context * @param session the BoxSession to use to get parameters required to authenticate via this * activity. * @param loginViaBoxApp Whether login should be handled by the installed box android app. Set * this to true only when you are sure or want to make sure user installed box android app and * want to use box android app to login. * @return intent to launch OAuthActivity. */ public static Intent createOAuthActivityIntent( final Context context, BoxSession session, boolean loginViaBoxApp) { Intent intent = createOAuthActivityIntent( context, session.getClientId(), session.getClientSecret(), session.getRedirectUrl(), loginViaBoxApp); intent.putExtra(EXTRA_SESSION, session); if (!SdkUtils.isEmptyString(session.getUserId())) { intent.putExtra(EXTRA_USER_ID_RESTRICTION, session.getUserId()); } return intent; }
/** * Create intent to launch OAuthActivity. Notes about redirect url parameter: If you already set * redirect url in <a href="https://cloud.app.box.com/developers/services">box dev console</a>, * you should pass in the same redirect url or use null for redirect url. If you didn't set it in * box dev console, you should pass in a url. In case you don't have a redirect server you can * simply use "http://localhost". * * @param context context * @param clientId your box client id * @param clientSecret your box client secret * @param redirectUrl redirect url, if you already set redirect url in <a * href="https://cloud.app.box.com/developers/services">box dev console</a>, leave this null * or use the same url, otherwise this field is required. You can use "http://localhost" if * you don't have a redirect server. * @param loginViaBoxApp Whether login should be handled by the installed box android app. Set * this to true only when you are sure or want to make sure user installed box android app and * want to use box android app to login. * @return intent to launch OAuthActivity. */ public static Intent createOAuthActivityIntent( final Context context, final String clientId, final String clientSecret, String redirectUrl, boolean loginViaBoxApp) { Intent intent = new Intent(context, OAuthActivity.class); intent.putExtra(BoxConstants.KEY_CLIENT_ID, clientId); intent.putExtra(BoxConstants.KEY_CLIENT_SECRET, clientSecret); if (!SdkUtils.isEmptyString(redirectUrl)) { intent.putExtra(BoxConstants.KEY_REDIRECT_URL, redirectUrl); } intent.putExtra(LOGIN_VIA_BOX_APP, loginViaBoxApp); return intent; }
private void clearCachedAuthenticationData() { if (oauthView != null) { oauthView.clearCache(true); oauthView.clearFormData(); oauthView.clearHistory(); } // wipe out cookies. CookieSyncManager.createInstance(this); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.removeAllCookie(); deleteDatabase("webview.db"); deleteDatabase("webviewCache.db"); File cacheDirectory = getCacheDir(); SdkUtils.deleteFolderRecursive(cacheDirectory); cacheDirectory.mkdir(); }
/** * @return the user id associated with the only logged in user. If no user is logged in or * multiple users are logged in returns null. */ private static String getBestStoredUserId(final Context context) { String lastAuthenticatedUserId = BoxAuthentication.getInstance().getLastAuthenticatedUserId(context); Map<String, BoxAuthentication.BoxAuthenticationInfo> authInfoMap = BoxAuthentication.getInstance().getStoredAuthInfo(context); if (authInfoMap != null) { if (!SdkUtils.isEmptyString(lastAuthenticatedUserId) && authInfoMap.get(lastAuthenticatedUserId) != null) { return lastAuthenticatedUserId; } if (authInfoMap.size() == 1) { for (String authUserId : authInfoMap.keySet()) { return authUserId; } } } return null; }
/** Callback method to be called when authentication failed. */ public boolean onAuthFailure(AuthFailure failure) { if (failure.type == OAuthWebView.AuthFailure.TYPE_WEB_ERROR) { if (failure.mWebException.getErrorCode() == WebViewClient.ERROR_CONNECT || failure.mWebException.getErrorCode() == WebViewClient.ERROR_HOST_LOOKUP || failure.mWebException.getErrorCode() == WebViewClient.ERROR_TIMEOUT) { return false; } Resources resources = this.getResources(); Toast.makeText( this, String.format( "%s\n%s: %s", resources.getString(com.box.sdk.android.R.string.boxsdk_Authentication_fail), resources.getString(com.box.sdk.android.R.string.boxsdk_details), failure.mWebException.getErrorCode() + " " + failure.mWebException.getDescription()), Toast.LENGTH_LONG) .show(); } else if (SdkUtils.isEmptyString(failure.message)) { Toast.makeText(this, R.string.boxsdk_Authentication_fail, Toast.LENGTH_LONG).show(); } else { switch (failure.type) { case AuthFailure.TYPE_URL_MISMATCH: Resources resources = this.getResources(); Toast.makeText( this, String.format( "%s\n%s: %s", resources.getString(R.string.boxsdk_Authentication_fail), resources.getString(R.string.boxsdk_details), resources.getString(R.string.boxsdk_Authentication_fail_url_mismatch)), Toast.LENGTH_LONG) .show(); break; default: Toast.makeText(this, R.string.boxsdk_Authentication_fail, Toast.LENGTH_LONG).show(); } } finish(); return true; }
/** * A BoxSession is responsible for maintaining the mapping between user and authentication tokens */ public class BoxSession extends BoxObject implements BoxAuthentication.AuthListener { private static final ThreadPoolExecutor AUTH_CREATION_EXECUTOR = SdkUtils.createDefaultThreadPoolExecutor(1, 20, 3600, TimeUnit.SECONDS); private String mUserAgent = "com.box.sdk.android"; private Context mApplicationContext; private BoxAuthentication.AuthListener sessionAuthListener; private String mUserId; protected String mClientId; protected String mClientSecret; protected String mClientRedirectUrl; protected BoxAuthentication.BoxAuthenticationInfo mAuthInfo; /** Optional refresh provider. */ protected BoxAuthentication.AuthenticationRefreshProvider mRefreshProvider; protected boolean mEnableBoxAppAuthentication = BoxConfig.ENABLE_BOX_APP_AUTHENTICATION; /** * When using this constructor, if a user has previously been logged in/stored or there is only * one user, this user will be authenticated. If no user or multiple users have been stored * without knowledge of the last one authenticated, ui will be shown to handle the scenario * similar to BoxSession(null, context). * * @param context current context. */ public BoxSession(Context context) { this(context, getBestStoredUserId(context)); } /** * @return the user id associated with the only logged in user. If no user is logged in or * multiple users are logged in returns null. */ private static String getBestStoredUserId(final Context context) { String lastAuthenticatedUserId = BoxAuthentication.getInstance().getLastAuthenticatedUserId(context); Map<String, BoxAuthentication.BoxAuthenticationInfo> authInfoMap = BoxAuthentication.getInstance().getStoredAuthInfo(context); if (authInfoMap != null) { if (!SdkUtils.isEmptyString(lastAuthenticatedUserId) && authInfoMap.get(lastAuthenticatedUserId) != null) { return lastAuthenticatedUserId; } if (authInfoMap.size() == 1) { for (String authUserId : authInfoMap.keySet()) { return authUserId; } } } return null; } /** * When setting the userId to null ui will be shown to ask which user to authenticate as if at * least one user is logged in. If no user has been stored will show login ui. If logging in as a * valid user id no ui will be displayed. * * @param userId user id to login as or null to login a new user. * @param context current context. */ public BoxSession(Context context, String userId) { this(context, userId, BoxConfig.CLIENT_ID, BoxConfig.CLIENT_SECRET, BoxConfig.REDIRECT_URL); } /** * Create a BoxSession using a specific box clientId, secret, and redirectUrl. This constructor is * not necessary unless an application uses multiple api keys. Note: When setting the userId to * null ui will be shown to ask which user to authenticate as if at least one user is logged in. * If no user has been stored will show login ui. * * @param context current context. * @param clientId the developer's client id to access the box api. * @param clientSecret the developer's secret used to interpret the response coming from Box. * @param redirectUrl the developer's redirect url to use for authenticating via Box. * @param userId user id to login as or null to login as a new user. */ public BoxSession( Context context, String userId, String clientId, String clientSecret, String redirectUrl) { mClientId = clientId; mClientSecret = clientSecret; mClientRedirectUrl = redirectUrl; if (SdkUtils.isEmptyString(mClientId) || SdkUtils.isEmptyString(mClientSecret)) { throw new RuntimeException( "Session must have a valid client id and client secret specified."); } mApplicationContext = context.getApplicationContext(); if (!SdkUtils.isEmptyString(userId)) { mAuthInfo = BoxAuthentication.getInstance().getAuthInfo(userId, context); mUserId = userId; } if (mAuthInfo == null) { mUserId = userId; mAuthInfo = new BoxAuthentication.BoxAuthenticationInfo(); } mAuthInfo.setClientId(mClientId); setupSession(); } /** * Construct a new box session object based off of an existing session. * * @param session session to use as the base. */ protected BoxSession(BoxSession session) { this.mApplicationContext = session.mApplicationContext; this.mAuthInfo = session.getAuthInfo(); setupSession(); } /** * This is an advanced constructor that can be used when implementing an authentication flow that * differs from the default oauth 2 flow. * * @param context current context. * @param authInfo authentication information that should be used. (Must at the minimum provide an * access token). * @param refreshProvider the refresh provider to use when the access token expires and needs to * be refreshed. */ public BoxSession( Context context, BoxAuthentication.BoxAuthenticationInfo authInfo, BoxAuthentication.AuthenticationRefreshProvider refreshProvider) { mApplicationContext = context.getApplicationContext(); mAuthInfo = authInfo; mRefreshProvider = refreshProvider; if (authInfo.getUser() != null) { if (!SdkUtils.isBlank(authInfo.getUser().getId())) { mUserId = authInfo.getUser().getId(); } } } /** * This is a convenience constructor. It is the equivalent of calling BoxSession(context, * authInfo, refreshProvider) and creating an authInfo with just an accessToken. * * @param context current context * @param accessToken a valid accessToken. * @param refreshProvider the refresh provider to use when the access token expires and needs to * refreshed. */ public BoxSession( Context context, String accessToken, BoxAuthentication.AuthenticationRefreshProvider refreshProvider) { this(context, createSimpleBoxAuthenticationInfo(accessToken), refreshProvider); } private static BoxAuthentication.BoxAuthenticationInfo createSimpleBoxAuthenticationInfo( final String accessToken) { BoxAuthentication.BoxAuthenticationInfo info = new BoxAuthentication.BoxAuthenticationInfo(); info.setAccessToken(accessToken); return info; } /** * Sets whether or not Box App authentication is enabled or not. * * @param enabled true if the session should try to authenticate via the Box application, false * otherwise. */ public void setEnableBoxAppAuthentication(boolean enabled) { mEnableBoxAppAuthentication = enabled; } /** * @return true if authentication via the Box App is enabled (this is by default), false * otherwise. */ public boolean isEnabledBoxAppAuthentication() { return mEnableBoxAppAuthentication; } /** @return the application context used to construct this session. */ public Context getApplicationContext() { return mApplicationContext; } /** * @param listener listener to notify when authentication events (authentication, refreshing, and * their exceptions) occur. */ public void setSessionAuthListener(BoxAuthentication.AuthListener listener) { this.sessionAuthListener = listener; } protected void setupSession() { // Because BuildConfig.DEBUG is always false when library projects publish their release // variants we use ApplicationInfo boolean isDebug = false; try { if (mApplicationContext != null && mApplicationContext.getPackageManager() != null) { PackageInfo info = mApplicationContext .getPackageManager() .getPackageInfo(mApplicationContext.getPackageName(), 0); isDebug = ((info.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0); } } catch (PackageManager.NameNotFoundException e) { // Do nothing -- debug mode will default to false } BoxConfig.IS_DEBUG = isDebug; BoxAuthentication.getInstance().addListener(this); } /** * @return the user associated with this session. May return null if this is a new session before * authentication. */ public BoxUser getUser() { return mAuthInfo.getUser(); } /** * @return the user id associated with this session. This can be null if the session was created * without a user id and has not been authenticated. */ public String getUserId() { return mUserId; } protected void setUserId(String userId) { mUserId = userId; } /** @return the auth information associated with this session. */ public BoxAuthentication.BoxAuthenticationInfo getAuthInfo() { return mAuthInfo; } /** * @return the custom refresh provider associated with this session. returns null if one is not * set. */ public BoxAuthentication.AuthenticationRefreshProvider getRefreshProvider() { return mRefreshProvider; } /** @return the user agent to use for network requests with this session. */ public String getUserAgent() { return mUserAgent; } /** * @return a box future task (already submitted to an executor) that starts the process of * authenticating this user. The task can be used to block until the user has completed * authentication through whatever ui is necessary(using task.get()). */ public BoxFutureTask<BoxSession> authenticate() { BoxSessionAuthCreationRequest req = new BoxSessionAuthCreationRequest(this, mEnableBoxAppAuthentication); BoxFutureTask<BoxSession> task = req.toTask(); AUTH_CREATION_EXECUTOR.submit(task); return task; } /** * Logout the currently authenticated user. * * @return a task that can be used to block until the user associated with this session has been * logged out. */ public BoxFutureTask<BoxSession> logout() { final BoxFutureTask<BoxSession> task = (new BoxSessionLogoutRequest(this)).toTask(); new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { task.run(); return null; } }.execute(); return task; } /** * Refresh authentication information associated with this session. * * @return a task that can be used to block until the information associated with this session has * been refreshed. */ public BoxFutureTask<BoxSession> refresh() { final BoxFutureTask<BoxSession> task = (new BoxSessionRefreshRequest(this)).toTask(); new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { task.run(); return null; } }.execute(); return task; } /** * Create a shared link session based off of the current session. * * @param sharedLinkUri The url of the shared link. * @return a session that can access a given shared link url and its children. */ public BoxSharedLinkSession getSharedLinkSession(String sharedLinkUri) { return new BoxSharedLinkSession(sharedLinkUri, this); } /** * Called when this session has been refreshed with new authentication info. * * @param info the latest info from a successful refresh. */ @Override public void onRefreshed(BoxAuthentication.BoxAuthenticationInfo info) { if (sameUser(info)) { BoxAuthentication.BoxAuthenticationInfo.cloneInfo(mAuthInfo, info); if (sessionAuthListener != null) { sessionAuthListener.onRefreshed(info); } } } /** * Called when this user has logged in. * * @param info the latest info from going through the login flow. */ @Override public void onAuthCreated(BoxAuthentication.BoxAuthenticationInfo info) { if (sameUser(info)) { BoxAuthentication.BoxAuthenticationInfo.cloneInfo(mAuthInfo, info); if (sessionAuthListener != null) { sessionAuthListener.onAuthCreated(info); } } } /** * Called when a failure occurs trying to authenticate or refresh. * * @param info The last authentication information available, before the exception. * @param ex the exception that occurred. */ @Override public void onAuthFailure(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) { if (sameUser(info) || (info == null && getUserId() == null)) { if (sessionAuthListener != null) { sessionAuthListener.onAuthFailure(info, ex); } if (ex instanceof BoxException) { BoxException.ErrorType errorType = ((BoxException) ex).getErrorType(); switch (errorType) { case NETWORK_ERROR: toastString(mApplicationContext, R.string.boxsdk_error_network_connection); } } } } private static AtomicLong mLastToastTime = new AtomicLong(); private static void toastString(final Context context, final int id) { Handler handler = new Handler(Looper.getMainLooper()); long currentTime = System.currentTimeMillis(); long lastToastTime = mLastToastTime.get(); if (currentTime - 3000 < lastToastTime) { return; } mLastToastTime.set(currentTime); handler.post( new Runnable() { @Override public void run() { Toast.makeText(context, id, Toast.LENGTH_SHORT).show(); } }); } @Override public void onLoggedOut(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) { if (sameUser(info)) { if (ex instanceof BoxAuthentication.NonDefaultClientLogoutException) { logout(); } else if (sessionAuthListener != null) { sessionAuthListener.onLoggedOut(info, ex); } } } /** * Returns the associated client id. If none is set, the one defined in BoxConfig will be used * * @return the client id this session is associated with. */ public String getClientId() { return mClientId; } /** * Returns the associated client secret. Because client secrets are not managed by the SDK, if * another client id/secret is used aside from the one defined in the BoxConfig * * @return the client secret this session is associated with */ public String getClientSecret() { return mClientSecret; } /** @return the redirect url this session is using. By default comes from BoxConstants. */ public String getRedirectUrl() { return mClientRedirectUrl; } private boolean sameUser(BoxAuthentication.BoxAuthenticationInfo info) { return info != null && info.getUser() != null && getUserId() != null && getUserId().equals(info.getUser().getId()); } private static class BoxSessionLogoutRequest extends BoxRequest<BoxSession, BoxSessionLogoutRequest> { private BoxSession mSession; public BoxSessionLogoutRequest(BoxSession session) { super(null, " ", null); this.mSession = session; } public BoxSession send() throws BoxException { synchronized (mSession) { if (mSession.getUser() != null) { BoxAuthentication.getInstance().logout(mSession); mSession.getAuthInfo().wipeOutAuth(); } } return mSession; } } private static class BoxSessionRefreshRequest extends BoxRequest<BoxSession, BoxSessionRefreshRequest> { private BoxSession mSession; public BoxSessionRefreshRequest(BoxSession session) { super(null, " ", null); this.mSession = session; } public BoxSession send() throws BoxException { try { // block until this session is finished refreshing. BoxAuthentication.BoxAuthenticationInfo refreshedInfo = BoxAuthentication.getInstance().refresh(mSession).get(); } catch (Exception e) { BoxException r = (BoxException) e.getCause(); if (e.getCause() instanceof BoxException) { throw (BoxException) e.getCause(); } else { throw new BoxException("BoxSessionRefreshRequest failed", e); } } BoxAuthentication.BoxAuthenticationInfo.cloneInfo( mSession.mAuthInfo, BoxAuthentication.getInstance() .getAuthInfo(mSession.getUserId(), mSession.getApplicationContext())); return mSession; } } private static class BoxSessionAuthCreationRequest extends BoxRequest<BoxSession, BoxSessionAuthCreationRequest> implements BoxAuthentication.AuthListener { private final BoxSession mSession; private CountDownLatch authLatch; public BoxSessionAuthCreationRequest(BoxSession session, boolean viaBoxApp) { super(null, " ", null); this.mSession = session; } public BoxSession send() throws BoxException { synchronized (mSession) { if (mSession.getUser() == null) { if (mSession.getAuthInfo() != null && !SdkUtils.isBlank(mSession.getAuthInfo().accessToken())) { // if we have an access token, but no user try to repair by making the call to user // endpoint. try { // TODO: show some ui while requestion user info BoxApiUser apiUser = new BoxApiUser(mSession); BoxUser user = apiUser.getCurrentUserInfoRequest().send(); mSession.setUserId(user.getId()); mSession.getAuthInfo().setUser(user); mSession.onAuthCreated(mSession.getAuthInfo()); return mSession; } catch (BoxException e) { BoxLogUtils.e("BoxSession", "Unable to repair user", e); if (e instanceof BoxException.RefreshFailure && ((BoxException.RefreshFailure) e).isErrorFatal()) { // if the refresh failure is unrecoverable have the user login again. toastString(mSession.getApplicationContext(), R.string.boxsdk_error_fatal_refresh); } else if (e.getErrorType() == BoxException.ErrorType.TERMS_OF_SERVICE_REQUIRED) { toastString( mSession.getApplicationContext(), R.string.boxsdk_error_terms_of_service); } else { mSession.onAuthFailure(null, e); throw e; } } // at this point we were unable to repair. } BoxAuthentication.getInstance().addListener(this); launchAuthUI(); return mSession; } else { BoxAuthentication.BoxAuthenticationInfo info = BoxAuthentication.getInstance() .getAuthInfo(mSession.getUserId(), mSession.getApplicationContext()); if (info != null) { BoxAuthentication.BoxAuthenticationInfo.cloneInfo(mSession.mAuthInfo, info); mSession.onAuthCreated(mSession.getAuthInfo()); } else { // Fail to get information of current user. current use no longer valid. mSession.mAuthInfo.setUser(null); launchAuthUI(); } } return mSession; } } private void launchAuthUI() { authLatch = new CountDownLatch(1); new Handler(Looper.getMainLooper()) .post( new Runnable() { @Override public void run() { if (mSession.getRefreshProvider() != null && mSession .getRefreshProvider() .launchAuthUi(mSession.getUserId(), mSession)) { // Do nothing authentication ui will be handled by developer. } else { BoxAuthentication.getInstance().startAuthenticationUI(mSession); } } }); try { authLatch.await(); } catch (InterruptedException e) { authLatch.countDown(); } } @Override public void onRefreshed(BoxAuthentication.BoxAuthenticationInfo info) { // Do not implement, this class itself only handles auth creation, regardless success or not, // failure should be handled by caller. } @Override public void onAuthCreated(BoxAuthentication.BoxAuthenticationInfo info) { BoxAuthentication.BoxAuthenticationInfo.cloneInfo(mSession.mAuthInfo, info); mSession.setUserId(info.getUser().getId()); mSession.onAuthCreated(info); authLatch.countDown(); } @Override public void onAuthFailure(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) { authLatch.countDown(); // Do not implement, this class itself only handles auth creation, regardless success or not, // failure should be handled by caller. } @Override public void onLoggedOut(BoxAuthentication.BoxAuthenticationInfo info, Exception ex) { // Do not implement, this class itself only handles auth creation, regardless success or not, // failure should be handled by caller. } } }