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