001package com.box.sdk; 002 003import com.eclipsesource.json.JsonObject; 004import java.io.UnsupportedEncodingException; 005import java.net.MalformedURLException; 006import java.net.URL; 007import java.net.URLEncoder; 008 009/** 010 * Represents an authenticated transactional connection to the Box API. 011 * 012 * <p>This class handles everything for transactional API that isn't already handled by BoxAPIConnection.</p> 013 */ 014public class BoxTransactionalAPIConnection extends BoxAPIConnection { 015 016 private static final String SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token"; 017 private static final String GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange"; 018 019 /** 020 * Constructs a new BoxTransactionalAPIConnection that authenticates with an access token. 021 * 022 * @param accessToken a transactional auth access token. 023 */ 024 public BoxTransactionalAPIConnection(String accessToken) { 025 super(accessToken); 026 super.setAutoRefresh(false); 027 } 028 029 /** 030 * Request a scoped transactional token. 031 * 032 * @param accessToken application access token. 033 * @param scope scope of transactional token. 034 * @return a BoxAPIConnection which can be used to perform transactional requests. 035 */ 036 public static BoxAPIConnection getTransactionConnection(String accessToken, String scope) { 037 return BoxTransactionalAPIConnection.getTransactionConnection(accessToken, scope, null); 038 } 039 040 /** 041 * Request a scoped transactional token for a particular resource. 042 * 043 * @param accessToken application access token. 044 * @param scope scope of transactional token. 045 * @param resource resource transactional token has access to. 046 * @return a BoxAPIConnection which can be used to perform transactional requests. 047 */ 048 public static BoxAPIConnection getTransactionConnection(String accessToken, String scope, String resource) { 049 BoxAPIConnection apiConnection = new BoxAPIConnection(accessToken); 050 051 URL url; 052 try { 053 url = new URL(apiConnection.getTokenURL()); 054 } catch (MalformedURLException e) { 055 assert false : "An invalid token URL indicates a bug in the SDK."; 056 throw new RuntimeException("An invalid token URL indicates a bug in the SDK.", e); 057 } 058 059 String urlParameters; 060 try { 061 urlParameters = String.format("grant_type=%s&subject_token=%s&subject_token_type=%s&scope=%s", GRANT_TYPE, 062 URLEncoder.encode(accessToken, "UTF-8"), SUBJECT_TOKEN_TYPE, URLEncoder.encode(scope, "UTF-8")); 063 064 if (resource != null) { 065 urlParameters += "&resource=" + URLEncoder.encode(resource, "UTF-8"); 066 } 067 } catch (UnsupportedEncodingException e) { 068 throw new BoxAPIException( 069 "An error occurred while attempting to encode url parameters for a transactional token request" 070 ); 071 } 072 073 BoxAPIRequest request = new BoxAPIRequest(apiConnection, url, "POST"); 074 request.shouldAuthenticate(false); 075 request.setBody(urlParameters); 076 077 BoxJSONResponse response = (BoxJSONResponse) request.send(); 078 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 079 080 final String fileToken = responseJSON.get("access_token").asString(); 081 BoxTransactionalAPIConnection transactionConnection = new BoxTransactionalAPIConnection(fileToken); 082 transactionConnection.setExpires(responseJSON.get("expires_in").asLong() * 1000); 083 084 return transactionConnection; 085 } 086 087 /** 088 * Disabling the non-Box Developer Edition authenticate method. 089 * 090 * @param authCode an auth code obtained from the first half of the OAuth process. 091 * @throws UnsupportedOperationException Box Transactional API does not support authentication with an auth code 092 */ 093 @Override 094 public void authenticate(String authCode) { 095 throw new UnsupportedOperationException( 096 "BoxTransactionalAPIConnection does not support the authenticate method." 097 ); 098 } 099 100 /** 101 * BoxTransactionalAPIConnection can never refresh. 102 * 103 * @return false always. 104 */ 105 @Override 106 public boolean canRefresh() { 107 return false; 108 } 109 110 /** 111 * Auto refresh is not available for transactional auth. 112 * 113 * @param autoRefresh true to enable auto token refresh; otherwise false. 114 * @throws UnsupportedOperationException Box Transactional API tokens can not be refreshed 115 */ 116 @Override 117 public void setAutoRefresh(boolean autoRefresh) { 118 throw new UnsupportedOperationException( 119 "BoxTransactionalAPIConnection does not support token refreshing, " 120 + "access tokens can be generated in the developer console." 121 ); 122 } 123 124 /** 125 * Transactional auth does not support token refreshes. 126 * 127 * @throws UnsupportedOperationException Box Transactional API tokens can not be refreshed 128 */ 129 @Override 130 public void refresh() { 131 throw new UnsupportedOperationException( 132 "BoxTransactionalAPIConnection does not support token refreshing, " 133 + "access tokens can be generated in the developer console." 134 ); 135 } 136}