Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: throw BoxApiError in C# fetch, add additional data to ResponseInfo (box/box-codegen#439) #23

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .codegen.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "engineHash": "df5b5de", "specHash": "b2f7568", "version": "0.1.0" }
7 changes: 3 additions & 4 deletions Box.Sdk.Gen.Tests.Integration/Test/Auth/AuthManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,12 @@ public async System.Threading.Tasks.Task TestDeveloperTokenAuth() {
public async System.Threading.Tasks.Task TestOauthAuthRevoke() {
OAuthConfig config = new OAuthConfig(clientId: Utils.GetEnvVar(name: "CLIENT_ID"), clientSecret: Utils.GetEnvVar(name: "CLIENT_SECRET"));
BoxOAuth auth = new BoxOAuth(config: config);
BoxClient client = new BoxClient(auth: auth);
AccessToken token = await GetAccessTokenAsync().ConfigureAwait(false);
await auth.TokenStorage.StoreAsync(token: token).ConfigureAwait(false);
AccessToken? tokenBeforeRevoke = await auth.TokenStorage.GetAsync().ConfigureAwait(false);
await client.Users.GetUserMeAsync().ConfigureAwait(false);
await auth.RevokeTokenAsync().ConfigureAwait(false);
AccessToken? tokenAfterRevoke = await auth.TokenStorage.GetAsync().ConfigureAwait(false);
Assert.IsTrue(tokenBeforeRevoke != null);
Assert.IsTrue(tokenAfterRevoke == null);
await Assert.That.IsExceptionAsync(async() => await client.Users.GetUserMeAsync().ConfigureAwait(false));
}

[TestMethod]
Expand Down
54 changes: 0 additions & 54 deletions Box.Sdk.Gen/Box/ApiException.cs

This file was deleted.

17 changes: 0 additions & 17 deletions Box.Sdk.Gen/Box/BoxSdkError.cs

This file was deleted.

7 changes: 6 additions & 1 deletion Box.Sdk.Gen/Box/CcgAuth/BoxCcgAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ public async System.Threading.Tasks.Task<AccessToken> RetrieveTokenAsync(Network
return oldToken;
}

public async System.Threading.Tasks.Task<string> RetrieveAuthorizationHeaderAsync(NetworkSession? networkSession = null) {
AccessToken token = await this.RetrieveTokenAsync(networkSession: networkSession).ConfigureAwait(false);
return string.Concat("Bearer ", token.AccessTokenField);
}

/// <summary>
/// Create a new BoxCCGAuth instance that uses the provided user ID as the subject ID.
/// May be one of this application's created App User. Depending on the configured User Access Level, may also be any other App User or Managed User in the enterprise.
Expand Down Expand Up @@ -114,7 +119,7 @@ public BoxCcgAuth AsEnterprise(string enterpriseId, ITokenStorage? tokenStorage
public async System.Threading.Tasks.Task<AccessToken> DownscopeTokenAsync(IReadOnlyList<string> scopes, string? resource = null, string? sharedLink = null, NetworkSession? networkSession = null) {
AccessToken? token = await this.TokenStorage.GetAsync().ConfigureAwait(false);
if (token == null) {
throw new BoxSdkError(message: "No access token is available. Make an API call to retrieve a token before calling this method.");
throw new BoxSdkException(message: "No access token is available. Make an API call to retrieve a token before calling this method.");
}
AuthorizationManager authManager = networkSession != null ? new AuthorizationManager(networkSession: networkSession) : new AuthorizationManager();
AccessToken downscopedToken = await authManager.RequestAccessTokenAsync(requestBody: new PostOAuth2Token(grantType: PostOAuth2TokenGrantTypeField.UrnIetfParamsOauthGrantTypeTokenExchange) { SubjectToken = token.AccessTokenField, SubjectTokenType = PostOAuth2TokenSubjectTokenTypeField.UrnIetfParamsOauthTokenTypeAccessToken, Resource = resource, Scope = string.Join(" ", scopes), BoxSharedLink = sharedLink }).ConfigureAwait(false);
Expand Down
7 changes: 6 additions & 1 deletion Box.Sdk.Gen/Box/DeveloperTokenAuth/BoxDeveloperTokenAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ public async System.Threading.Tasks.Task<AccessToken> RetrieveTokenAsync(Network
/// An object to keep network session state
/// </param>
public async System.Threading.Tasks.Task<AccessToken> RefreshTokenAsync(NetworkSession? networkSession = null) {
throw new BoxSdkError(message: "Developer token has expired. Please provide a new one.");
throw new BoxSdkException(message: "Developer token has expired. Please provide a new one.");
}

public async System.Threading.Tasks.Task<string> RetrieveAuthorizationHeaderAsync(NetworkSession? networkSession = null) {
AccessToken token = await this.RetrieveTokenAsync(networkSession: networkSession).ConfigureAwait(false);
return string.Concat("Bearer ", token.AccessTokenField);
}

}
Expand Down
17 changes: 17 additions & 0 deletions Box.Sdk.Gen/Box/Errors/BoxApiException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Errors
{
public class BoxApiException : BoxSdkException
{
public RequestInfo RequestInfo { get; set; }

public ResponseInfo ResponseInfo { get; set; }

public BoxApiException(string message, DateTimeOffset timeStamp, RequestInfo requestInfo, ResponseInfo responseInfo) : base(message, timeStamp, "BoxApiException")
{
RequestInfo = requestInfo;
ResponseInfo = responseInfo;
}
}
}
19 changes: 19 additions & 0 deletions Box.Sdk.Gen/Box/Errors/BoxSdkException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace Errors
{
public class BoxSdkException : Exception
{
public System.DateTimeOffset? Timestamp { get; set; } = default;

public string? Error { get; set; } = default;

public string Name { get; set; }

public BoxSdkException(string message, DateTimeOffset? timeStamp = null, string name = "BoxSdkException") : base(message)
{
Name = name;
Timestamp = timeStamp ?? DateTimeOffset.UtcNow;
}
}
}
26 changes: 26 additions & 0 deletions Box.Sdk.Gen/Box/Errors/RequestInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Errors
{
public class RequestInfo
{
public string Method { get; set; }

public string Url { get; set; }

public IReadOnlyDictionary<string, string> QueryParams { get; set; }

public IReadOnlyDictionary<string, string> Headers { get; set; }

public string? Body { get; set; } = default;

public RequestInfo(string method, string? url, IReadOnlyDictionary<string, string>? queryParams, IReadOnlyDictionary<string, string> headers)
{
Method = method;
Url = url ?? "";
QueryParams = queryParams ?? new ReadOnlyDictionary<string, string>(new Dictionary<string, string>());
Headers = headers;
}
}
}
56 changes: 56 additions & 0 deletions Box.Sdk.Gen/Box/Errors/ResponseInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Serialization.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Errors
{
public class ResponseInfo
{
public int StatusCode { get; set; }

public IReadOnlyDictionary<string, string> Headers { get; set; }

public SerializedData? Body { get; set; } = default;

public string? RawBody { get; set; } = default;

public string? Code { get; set; } = default;

public Dictionary<string, object>? ContextInfo { get; set; } = default;

public string? RequestId { get; set; } = default;

public string? HelpUrl { get; set; } = default;

public ResponseInfo(int statusCode, IReadOnlyDictionary<string, string> headers, SerializedData body, string rawBody,
string? code, Dictionary<string, object>? contextInfo, string? requestId, string? helpUrl)
{
StatusCode = statusCode;
Headers = headers;
Body = body;
RawBody = rawBody;
Code = code;
ContextInfo = contextInfo ?? new Dictionary<string, object>();
RequestId = requestId;
HelpUrl = helpUrl;
}
}

internal class BoxApiExceptionDetails
{
[JsonPropertyName("code")]
public string? Code { get; set; }

[JsonPropertyName("context_info")]
public Dictionary<string, object>? ContextInfo { get; set; }

[JsonPropertyName("request_id")]
public string? RequestId { get; set; }

[JsonPropertyName("help_url")]
public string? HelpUrl { get; set; }

public BoxApiExceptionDetails() { }
}

}
9 changes: 7 additions & 2 deletions Box.Sdk.Gen/Box/JwtAuth/BoxJwtAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public BoxJwtAuth(JwtConfig config) {
/// </param>
public async System.Threading.Tasks.Task<AccessToken> RefreshTokenAsync(NetworkSession? networkSession = null) {
if (Utils.IsBrowser()) {
throw new BoxSdkError(message: "JWT auth is not supported in browser environment.");
throw new BoxSdkException(message: "JWT auth is not supported in browser environment.");
}
JwtAlgorithm alg = this.Config.Algorithm != null ? NullableUtils.Unwrap(this.Config.Algorithm) : JwtAlgorithm.Rs256;
Dictionary<string, object> claims = new Dictionary<string, object>() { { "exp", Utils.GetEpochTimeInSeconds() + 30 }, { "box_sub_type", this.SubjectType } };
Expand Down Expand Up @@ -74,6 +74,11 @@ public async System.Threading.Tasks.Task<AccessToken> RetrieveTokenAsync(Network
return oldToken;
}

public async System.Threading.Tasks.Task<string> RetrieveAuthorizationHeaderAsync(NetworkSession? networkSession = null) {
AccessToken token = await this.RetrieveTokenAsync(networkSession: networkSession).ConfigureAwait(false);
return string.Concat("Bearer ", token.AccessTokenField);
}

/// <summary>
/// Create a new BoxJWTAuth instance that uses the provided user ID as the subject of the JWT assertion.
/// May be one of this application's created App User. Depending on the configured User Access Level, may also be any other App User or Managed User in the enterprise.
Expand Down Expand Up @@ -127,7 +132,7 @@ public BoxJwtAuth AsEnterprise(string userId, ITokenStorage? tokenStorage = defa
public async System.Threading.Tasks.Task<AccessToken> DownscopeTokenAsync(IReadOnlyList<string> scopes, string? resource = null, string? sharedLink = null, NetworkSession? networkSession = null) {
AccessToken? token = await this.TokenStorage.GetAsync().ConfigureAwait(false);
if (token == null) {
throw new BoxSdkError(message: "No access token is available. Make an API call to retrieve a token before calling this method.");
throw new BoxSdkException(message: "No access token is available. Make an API call to retrieve a token before calling this method.");
}
AuthorizationManager authManager = networkSession != null ? new AuthorizationManager(networkSession: networkSession) : new AuthorizationManager();
AccessToken downscopedToken = await authManager.RequestAccessTokenAsync(requestBody: new PostOAuth2Token(grantType: PostOAuth2TokenGrantTypeField.UrnIetfParamsOauthGrantTypeTokenExchange) { SubjectToken = token.AccessTokenField, SubjectTokenType = PostOAuth2TokenSubjectTokenTypeField.UrnIetfParamsOauthTokenTypeAccessToken, Resource = resource, Scope = string.Join(" ", scopes), BoxSharedLink = sharedLink }).ConfigureAwait(false);
Expand Down
10 changes: 7 additions & 3 deletions Box.Sdk.Gen/Box/Oauth/BoxOAuth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public async System.Threading.Tasks.Task<AccessToken> GetTokensAuthorizationCode
public async System.Threading.Tasks.Task<AccessToken> RetrieveTokenAsync(NetworkSession? networkSession = null) {
AccessToken? token = await this.TokenStorage.GetAsync().ConfigureAwait(false);
if (token == null) {
throw new BoxSdkError(message: "Access and refresh tokens not available. Authenticate before making any API call first.");
throw new BoxSdkException(message: "Access and refresh tokens not available. Authenticate before making any API call first.");
}
return token;
}
Expand All @@ -81,6 +81,11 @@ public async System.Threading.Tasks.Task<AccessToken> RefreshTokenAsync(NetworkS
return token;
}

public async System.Threading.Tasks.Task<string> RetrieveAuthorizationHeaderAsync(NetworkSession? networkSession = null) {
AccessToken token = await this.RetrieveTokenAsync(networkSession: networkSession).ConfigureAwait(false);
return string.Concat("Bearer ", token.AccessTokenField);
}

/// <summary>
/// Revoke an active Access Token, effectively logging a user out that has been previously authenticated.
/// </summary>
Expand All @@ -94,7 +99,6 @@ public async System.Threading.Tasks.Task RevokeTokenAsync(NetworkSession? networ
}
AuthorizationManager authManager = networkSession != null ? new AuthorizationManager(networkSession: networkSession) : new AuthorizationManager();
await authManager.RevokeAccessTokenAsync(requestBody: new PostOAuth2Revoke() { ClientId = this.Config.ClientId, ClientSecret = this.Config.ClientSecret, Token = token.AccessTokenField }).ConfigureAwait(false);
await this.TokenStorage.ClearAsync().ConfigureAwait(false);
}

/// <summary>
Expand All @@ -115,7 +119,7 @@ public async System.Threading.Tasks.Task RevokeTokenAsync(NetworkSession? networ
public async System.Threading.Tasks.Task<AccessToken> DownscopeTokenAsync(IReadOnlyList<string> scopes, string? resource = null, string? sharedLink = null, NetworkSession? networkSession = null) {
AccessToken? token = await this.TokenStorage.GetAsync().ConfigureAwait(false);
if (token == null || token.AccessTokenField == null) {
throw new BoxSdkError(message: "No access token is available.");
throw new BoxSdkException(message: "No access token is available.");
}
AuthorizationManager authManager = networkSession != null ? new AuthorizationManager(networkSession: networkSession) : new AuthorizationManager();
AccessToken downscopedToken = await authManager.RequestAccessTokenAsync(requestBody: new PostOAuth2Token(grantType: PostOAuth2TokenGrantTypeField.UrnIetfParamsOauthGrantTypeTokenExchange) { SubjectToken = token.AccessTokenField, SubjectTokenType = PostOAuth2TokenSubjectTokenTypeField.UrnIetfParamsOauthTokenTypeAccessToken, Scope = string.Join(" ", scopes), Resource = resource, BoxSharedLink = sharedLink }).ConfigureAwait(false);
Expand Down
4 changes: 3 additions & 1 deletion Box.Sdk.Gen/Networking/Auth/IAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ namespace Box.Sdk.Gen {
public interface IAuthentication {
public System.Threading.Tasks.Task<AccessToken> RetrieveTokenAsync(NetworkSession? networkSession = null);

public System.Threading.Tasks.Task<AccessToken> RefreshTokenAsync(NetworkSession networkSession);
public System.Threading.Tasks.Task<AccessToken> RefreshTokenAsync(NetworkSession? networkSession = null);

public System.Threading.Tasks.Task<string> RetrieveAuthorizationHeaderAsync(NetworkSession? networkSession = null);

}
}
Loading
Loading