11package cloud .stackit .sdk .core ;
22
33import cloud .stackit .sdk .core .config .CoreConfiguration ;
4+ import cloud .stackit .sdk .core .exception .ApiException ;
45import cloud .stackit .sdk .core .model .ServiceAccountKey ;
56import com .auth0 .jwt .JWT ;
67import com .auth0 .jwt .algorithms .Algorithm ;
@@ -63,10 +64,11 @@ public String getAccessToken() {
6364 * Creates the initial service account and refreshes expired access token.
6465 * @param cfg Configuration to set a custom token endpoint and the token expiration leeway.
6566 * @param saKey Service Account Key, which should be used for the authentication
66- * @throws InvalidKeySpecException Throws, when the private key in the service account can not be parsed
67- * @throws IOException Throws, when on unexpected responses from the key flow
67+ * @throws InvalidKeySpecException thrown when the private key in the service account can not be parsed
68+ * @throws IOException thrown on unexpected responses from the key flow
69+ * @throws ApiException thrown on unexpected responses from the key flow
6870 */
69- public KeyFlowAuthenticator (CoreConfiguration cfg , ServiceAccountKey saKey ) throws InvalidKeySpecException , IOException {
71+ public KeyFlowAuthenticator (CoreConfiguration cfg , ServiceAccountKey saKey ) throws InvalidKeySpecException , IOException , ApiException {
7072 this .saKey = saKey ;
7173 this .gson = new Gson ();
7274 this .httpClient = new OkHttpClient .Builder ()
@@ -86,50 +88,50 @@ public KeyFlowAuthenticator(CoreConfiguration cfg, ServiceAccountKey saKey) thro
8688 createAccessToken ();
8789 }
8890
89- public synchronized String getAccessToken () throws IOException {
91+
92+ /**
93+ * Returns access token. If the token is expired it creates a new token.
94+ * @throws IOException request for new access token failed
95+ * @throws ApiException response for new access token with bad status code
96+ */
97+ public synchronized String getAccessToken () throws IOException , ApiException {
9098 if (token == null || token .isExpired ()) {
9199 createAccessTokenWithRefreshToken ();
92100 }
93101 return token .getAccessToken ();
94102 }
95103
96104 /**
97- * Creates the inital accessToken and stores it in `this.token`
105+ * Creates the initial accessToken and stores it in `this.token`
98106 * @throws InvalidKeySpecException can not parse private key
99107 * @throws IOException request for access token failed
108+ * @throws ApiException response for new access token with bad status code
100109 * @throws JsonSyntaxException parsing of the created access token failed
101110 */
102- private void createAccessToken () throws InvalidKeySpecException , IOException , JsonSyntaxException {
111+ private void createAccessToken () throws InvalidKeySpecException , IOException , JsonSyntaxException , ApiException {
103112 String grant = "urn:ietf:params:oauth:grant-type:jwt-bearer" ;
104113 String assertion ;
105114 try {
106115 assertion = generateSelfSignedJWT ();
107116 } catch (NoSuchAlgorithmException e ) {
108117 throw new RuntimeException ("could not find required algorithm for jwt signing. This should not happen and should be reported on https://github.com/stackitcloud/stackit-sdk-java/issues" , e );
109118 }
110- try (Response response = requestToken (grant , assertion ).execute ()) {
111- parseTokenResponse (response );
112- } catch (IOException | ApiException e ) {
113- throw new IOException ("request for access token failed" , e );
114- } catch (JsonSyntaxException e ) {
115- throw new JsonSyntaxException ("parsing access token failed" , e );
119+ Response response = requestToken (grant , assertion ).execute ();
120+ parseTokenResponse (response );
121+ response .close ();
116122 }
117- }
118123
119124 /**
120125 * Creates a new access token with the existing refresh token
121126 * @throws IOException request for new access token failed
127+ * @throws ApiException response for new access token with bad status code
122128 * @throws JsonSyntaxException can not parse new access token
123129 */
124- private synchronized void createAccessTokenWithRefreshToken () throws IOException , JsonSyntaxException {
130+ private synchronized void createAccessTokenWithRefreshToken () throws IOException , JsonSyntaxException , ApiException {
125131 String refreshToken = token .refreshToken ;
126- try (Response response = requestToken (REFRESH_TOKEN , refreshToken ).execute ()) {
127- parseTokenResponse (response );
128- } catch (IOException | ApiException e ) {
129- throw new IOException ("request for new access token failed" , e );
130- } catch (JsonSyntaxException e ) {
131- throw new JsonSyntaxException ("parsing refreshed access token failed" , e );
132- }
132+ Response response = requestToken (REFRESH_TOKEN , refreshToken ).execute ();
133+ parseTokenResponse (response );
134+ response .close ();
133135 }
134136
135137 private synchronized void parseTokenResponse (Response response ) throws ApiException , JsonSyntaxException {
@@ -145,13 +147,9 @@ private synchronized void parseTokenResponse(Response response) throws ApiExcept
145147 throw new JsonSyntaxException ("body from token creation is null" );
146148 }
147149
148- try {
149- token = gson .fromJson (new InputStreamReader (response .body ().byteStream (), StandardCharsets .UTF_8 ), KeyFlowTokenResponse .class );
150- token .expiresIn = JWT .decode (token .accessToken ).getExpiresAt ().toInstant ().minusSeconds (tokenLeewayInSeconds ).getEpochSecond ();
151- response .body ().close ();
152- } catch (JsonSyntaxException e ) {
153- throw new JsonSyntaxException ("could not parse response of created token" , e );
154- }
150+ token = gson .fromJson (new InputStreamReader (response .body ().byteStream (), StandardCharsets .UTF_8 ), KeyFlowTokenResponse .class );
151+ token .expiresIn = JWT .decode (token .accessToken ).getExpiresAt ().toInstant ().minusSeconds (tokenLeewayInSeconds ).getEpochSecond ();
152+ response .body ().close ();
155153 }
156154
157155 private Call requestToken (String grant , String assertionValue ) throws IOException {
@@ -171,11 +169,8 @@ private Call requestToken(String grant, String assertionValue) throws IOExceptio
171169
172170 private String generateSelfSignedJWT () throws InvalidKeySpecException , NoSuchAlgorithmException {
173171 RSAPrivateKey prvKey ;
174- try {
175- prvKey = saKey .getCredentials ().getPrivateKeyParsed ();
176- } catch (InvalidKeySpecException e ) {
177- throw new InvalidKeySpecException ("could not parse private key" , e );
178- }
172+
173+ prvKey = saKey .getCredentials ().getPrivateKeyParsed ();
179174 Algorithm algorithm = Algorithm .RSA512 (prvKey );
180175
181176 Map <String , Object > jwtHeader = new HashMap <>();
0 commit comments