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