diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d81e68..ae55aa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,9 @@ This is the changelog for [Authress SDK](readme.md). ## 2.0 ## -* Renamed `AccessRecordStatements` and other models that end with `S` but aren't actually plural to be `AccessRecordStatement` (without the `S`). -* All APIs are now part of sub instance properties of the `AuthressClient` class, `AccessClient.AccessRecords` and `AccessClient.ServiceClients`, etc.. * `ApiBasePath` has been renamed to `AuthressApiUrl`. * `HttpClientSettings` Has been removed in favor of `AuthressSettings` Class. +* [Breaking] `UserPermissions.GetUserResources()` no longer returns the property `AccessToAllSubResources`. When a user only has access to parent resources, the list will always be empty unless the `CollectionConfigurationEnum` property is specified. ## 1.5 ## * Fix `DateTimeOffset` type assignments, properties that were incorrectly defined as `DateTime` are now correctly `DateTimeOffsets`. diff --git a/README.md b/README.md index e810573..9e64365 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The recommended solution is to use the C# built in OpenID provider by Microsoft. using Authress.SDK; // Get an authress custom domain: https://authress.io/app/#/settings?focus=domain -var authressSettings = new AuthressSettings { ApiBasePath = "https://authress.company.com", }; +var authressSettings = new AuthressSettings { AuthressApiUrl = "https://authress.company.com", }; var authressClient = new AuthressClient(tokenProvider, authressSettings) var verifiedUserIdentity = await authressClient.VerifyToken(jwtToken); @@ -60,7 +60,7 @@ namespace Microservice return accessToken; }); // Get an authress custom domain: https://authress.io/app/#/settings?focus=domain - var authressSettings = new AuthressSettings { ApiBasePath = "https://authress.company.com", }; + var authressSettings = new AuthressSettings { AuthressApiUrl = "https://authress.company.com", }; var authressClient = new AuthressClient(tokenProvider, authressSettings); // 2. At runtime attempt to Authorize the user for the resource @@ -86,7 +86,7 @@ namespace Microservice // automatically populate forward the users token // 1. instantiate all the necessary classes var tokenProvider = new ManualTokenProvider(); - var authressSettings = new AuthressSettings { ApiBasePath = "https://DOMAIN.api.authress.io", }; + var authressSettings = new AuthressSettings { AuthressApiUrl = "https://DOMAIN.api.authress.io", }; var authressClient = new AuthressClient(tokenProvider, authressSettings); // 2. At runtime attempt to Authorize the user for the resource @@ -117,7 +117,7 @@ namespace Microservice var decodedAccessKey = decrypt(accessKey); var tokenProvider = new AuthressClientTokenProvider(decodedAccessKey); // Get an authress custom domain: https://authress.io/app/#/settings?focus=domain - var authressSettings = new AuthressSettings { ApiBasePath = "https://authress.company.com", }; + var authressSettings = new AuthressSettings { AuthressApiUrl = "https://authress.company.com", }; var authressClient = new AuthressClient(tokenProvider, authressSettings); // Attempt to Authorize the user for the resource diff --git a/src/Authress.SDK/Api/IUserPermissionsApi.cs b/src/Authress.SDK/Api/IUserPermissionsApi.cs index 4d895f8..e01d8bb 100644 --- a/src/Authress.SDK/Api/IUserPermissionsApi.cs +++ b/src/Authress.SDK/Api/IUserPermissionsApi.cs @@ -11,7 +11,7 @@ namespace Authress.SDK.Api public interface IUserPermissionsApi { /// - /// Get the users resources. Get the users resources. This result is a list of resource uris that a user has an explicit permission to, a user with * access to all sub resources will return an empty list and {AccessToAllSubResources} will be populated. The list will be paginated. + /// Get the users resources. This result is a list of resource uris that a user has an permission to. By default only the top level matching resources are returned. To get a user's list of deeply nested resources, set the collectionConfiguration to be INCLUDE_NESTED. This collection is paginated. /// /// The user to check permissions on /// The uri path of a collection resource to fetch permissions for. diff --git a/src/Authress.SDK/Api/UserPermissionsApi.cs b/src/Authress.SDK/Api/UserPermissionsApi.cs index 304522c..4374e94 100644 --- a/src/Authress.SDK/Api/UserPermissionsApi.cs +++ b/src/Authress.SDK/Api/UserPermissionsApi.cs @@ -135,7 +135,7 @@ public async Task AuthorizeUser (string userId, string resourceUri, string permi } /// - /// Get the users resources. Get the users resources. This result is a list of resource uris that a user has an explicit permission to, a user with * access to all sub resources will return an empty list and {AccessToAllSubResources} will be populated. The list will be paginated. + /// Get the users resources. This result is a list of resource uris that a user has an permission to. By default only the top level matching resources are returned. To get a user's list of deeply nested resources, set the collectionConfiguration to be INCLUDE_NESTED. This collection is paginated. /// /// The user to check permissions on /// The uri path of a collection resource to fetch permissions for. @@ -152,56 +152,22 @@ public async Task GetUserResources(string userId, string resource throw new ArgumentNullException("Missing required parameter 'userId'."); } - if (collectionConfiguration == CollectionConfigurationEnum.INCLUDE_NESTED) + var queryParams = new Dictionary { - var queryParams = new Dictionary - { - { "resourceUri", resourceCollectionUri }, - { "permissions", permission }, - { "collectionConfiguration", collectionConfiguration.ToString() } - }; + { "resourceUri", resourceCollectionUri }, + { "permissions", permission }, + { "collectionConfiguration", collectionConfiguration.ToString() } + }; - var queryString = queryParams.Where(pair => !string.IsNullOrEmpty(pair.Value)) - .Select(pair => $"{pair.Key}={System.Web.HttpUtility.UrlEncode(pair.Value)}").Aggregate((next, total) => $"{total}&{next}"); - var path = $"/v1/users/{System.Web.HttpUtility.UrlEncode(userId)}/resources?{queryString}"; + var queryString = queryParams.Where(pair => !string.IsNullOrEmpty(pair.Value)) + .Select(pair => $"{pair.Key}={System.Web.HttpUtility.UrlEncode(pair.Value)}").Aggregate((next, total) => $"{total}&{next}"); + var path = $"/v1/users/{System.Web.HttpUtility.UrlEncode(userId)}/resources?{queryString}"; - var client = await authressHttpClientProvider.GetHttpClientAsync(); - using (var response = await client.GetAsync(path)) - { - await response.ThrowIfNotSuccessStatusCode(); - return await response.Content.ReadAsAsync(); - } - } - else + var client = await authressHttpClientProvider.GetHttpClientAsync(); + using (var response = await client.GetAsync(path)) { - - var queryParams = new Dictionary - { - { "resourceUri", resourceCollectionUri }, - { "permissions", permission } - }; - - var queryString = queryParams.Where(pair => !string.IsNullOrEmpty(pair.Value)) - .Select(pair => $"{pair.Key}={System.Web.HttpUtility.UrlEncode(pair.Value)}").Aggregate((next, total) => $"{total}&{next}"); - var path = $"/v1/users/{System.Web.HttpUtility.UrlEncode(userId)}/resources?{queryString}"; - - var client = await authressHttpClientProvider.GetHttpClientAsync(); - - var authorizeUserAsync = AuthorizeUser(userId, resourceCollectionUri, permission); - using (var response = await client.GetAsync(path)) - { - try - { - await authorizeUserAsync; - return new UserResources { UserId = userId, AccessToAllSubResources = true, Resources = null }; - } - catch (Exception) - { - /* Ignore if the user doesn't have permission or if there is a problem, instead fallback to looking up explicit resources by permission */ - } - await response.ThrowIfNotSuccessStatusCode(); - return await response.Content.ReadAsAsync(); - } + await response.ThrowIfNotSuccessStatusCode(); + return await response.Content.ReadAsAsync(); } } } diff --git a/src/Authress.SDK/Client/AuthressClient.cs b/src/Authress.SDK/Client/AuthressClient.cs index 9f38951..6dd7cc6 100644 --- a/src/Authress.SDK/Client/AuthressClient.cs +++ b/src/Authress.SDK/Client/AuthressClient.cs @@ -28,21 +28,7 @@ public AuthressClient(ITokenProvider tokenProvider, AuthressSettings settings, I throw new ArgumentNullException("Missing required parameter AuthressSettings"); } authressHttpClientProvider = new HttpClientProvider(settings, tokenProvider, customHttpClientHandlerFactory); - tokenVerifier = new TokenVerifier(settings.ApiBasePath, authressHttpClientProvider); - } - - /// - /// Deprecated Constructor - /// - public AuthressClient(ITokenProvider tokenProvider, HttpClientSettings settings, IHttpClientHandlerFactory customHttpClientHandlerFactory = null) - { - if (settings == null) { - throw new ArgumentNullException("Missing required parameter HttpClientSettings"); - } - authressHttpClientProvider = new HttpClientProvider( - new AuthressSettings { ApiBasePath = settings.ApiBasePath, RequestTimeout = settings.RequestTimeout }, - tokenProvider, customHttpClientHandlerFactory); - tokenVerifier = new TokenVerifier(settings.ApiBasePath, authressHttpClientProvider); + tokenVerifier = new TokenVerifier(settings.AuthressApiUrl, authressHttpClientProvider); } /// diff --git a/src/Authress.SDK/Client/HttpClientProvider.cs b/src/Authress.SDK/Client/HttpClientProvider.cs index 84be505..0867438 100644 --- a/src/Authress.SDK/Client/HttpClientProvider.cs +++ b/src/Authress.SDK/Client/HttpClientProvider.cs @@ -17,35 +17,19 @@ public interface IHttpClientHandlerFactory HttpClientHandler Create(); } - /// - /// Authress Domain Host: https://authress.company.com (Get an authress custom domain: https://authress.io/app/#/settings?focus=domain) - /// - public class HttpClientSettings - { - /// - /// Authress Domain Host: https://authress.company.com (Get an authress custom domain: https://authress.io/app/#/settings?focus=domain) - /// - public string ApiBasePath { get; set; } = "https://api.authress.io"; - - /// - /// Timeout for requests to Authress. Default is unset. - /// - public TimeSpan? RequestTimeout { get; set; } = null; - } - /// /// Authress Domain Host: https://authress.company.com (Get an authress custom domain: https://authress.io/app/#/settings?focus=domain) /// public class AuthressSettings { - private string apiBasePath = "https://api.authress.io"; + private string authressApiUrl = "https://api.authress.io"; /// /// Authress Domain Host: https://authress.company.com (Get an authress custom domain: https://authress.io/app/#/settings?focus=domain) /// - public string ApiBasePath { - get { return apiBasePath; } + public string AuthressApiUrl { + get { return authressApiUrl; } set { - apiBasePath = Sanitizers.SanitizeUrl(value); + authressApiUrl = Sanitizers.SanitizeUrl(value); } } @@ -116,8 +100,8 @@ public async Task GetHttpClientAsync() // List of Handlers that never need to be retried outermostHandler = new OptimisticPerformanceHandler(outermostHandler, settings.CacheFallbackNormTimeout); - outermostHandler = new RewriteBaseUrlHandler(outermostHandler, settings.ApiBasePath); - outermostHandler = new AddAuthorizationHeaderHandler(outermostHandler, tokenProvider, settings.ApiBasePath); + outermostHandler = new RewriteBaseUrlHandler(outermostHandler, settings.AuthressApiUrl); + outermostHandler = new AddAuthorizationHeaderHandler(outermostHandler, tokenProvider, settings.AuthressApiUrl); outermostHandler = new AddUserAgentHeaderHandler(outermostHandler); /**** ⌃ Called First ⌃ ******/ @@ -128,7 +112,7 @@ public async Task GetHttpClientAsync() clientProxy.Timeout = settings.RequestTimeout.Value; } - clientProxy.BaseAddress = new Uri(settings.ApiBasePath); + clientProxy.BaseAddress = new Uri(settings.AuthressApiUrl); return clientProxy; } finally diff --git a/src/Authress.SDK/Model/UserResources.cs b/src/Authress.SDK/Model/UserResources.cs index 3274d2e..7e9730e 100644 --- a/src/Authress.SDK/Model/UserResources.cs +++ b/src/Authress.SDK/Model/UserResources.cs @@ -34,10 +34,5 @@ public class UserResources : IPaginationDto [DataMember(Name = "links", EmitDefaultValue = false)] [JsonProperty(PropertyName = "links")] public Links Links { get; set; } - - /// - /// If the user has access to all sub-resources, then instead of resources being a list, this property will be populated `true`. - /// - public bool AccessToAllSubResources { get; set; } = false; } }