Skip to content

Commit

Permalink
3.0 Release.
Browse files Browse the repository at this point in the history
  • Loading branch information
wparad committed Sep 29, 2024
1 parent 2031b05 commit 5479a71
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 53 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Change log
This is the changelog for [Authress SDK](readme.md).

## 3.0 ##
* [Breaking] UserId is now required in all `userPermissions` apis. This improves **Security By Default** requiring explicit check on who the user is.
* [Breaking] Removal of property `accessToAllSubResources`.

## 2.3 ##
* Require minimum Node version to be 16.
* Improve support for collectionConfiguration to skip `accessToAllSubResources` check when using `INCLUDE_NESTED` in the query.
Expand Down
22 changes: 11 additions & 11 deletions src/userPermissions/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,45 @@ export interface UserPermissionsApi {
/**
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> Does the user have the specified permissions to the resource?
* @summary Check to see if a user has permissions to a resource.
* @param {string} [userId] The user to check permissions on
* @param {string} userId The user to check permissions on
* @param {string} resourceUri The uri path of a resource to validate, must be URL encoded, uri segments are allowed, the resource must be a full path, and permissions are not inherited by sub-resources.
* @param {string} permission Permission to check, &#x27;*&#x27; and scoped permissions can also be checked here.
* @throws {ArgumentRequiredError}
* @throws {UnauthorizedError}
*/
// @ts-ignore
authorizeUser(userId?: string | null, resourceUri: string, permission: string): Promise<Response<void>>;
authorizeUser(userId: string, resourceUri: string, permission: string): Promise<Response<void>>;
/**
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> Permanently disable a token. To be used after the token has completed its use. Should be called on all tokens to ensure they are not active indefinitely.
* @summary Disable a token
* @param {string} [userId] The user to create an impersonation token for.
* @param {string} userId The user to create an impersonation token for.
* @param {string} tokenId The relevant token identifier
* @throws {ArgumentRequiredError}
*/
// @ts-ignore
disableUserToken(userId?: string | null, tokenId: string): Promise<Response<void>>;
disableUserToken(userId: string, tokenId: string): Promise<Response<void>>;
/**
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> Get a summary of the permissions a user has to a particular resource.
* @summary Get the permissions a user has to a resource.
* @param {string} [userId] The user to check permissions on
* @param {string} userId The user to check permissions on
* @param {string} resourceUri The uri path of a resource to validate, must be URL encoded, uri segments are allowed.
* @throws {ArgumentRequiredError}
*/
// @ts-ignore
getUserPermissionsForResource(userId?: string | null, resourceUri: string): Promise<Response<UserPermissions>>;
getUserPermissionsForResource(userId: string, resourceUri: string): Promise<Response<UserPermissions>>;
/**
* <i class="far fa-money-bill-alt text-primary"></i> <span class="text-primary">Billable</span> Get a summary of the roles a user has to a particular resource. Users can be assigned roles from multiple access records, this may cause the same role to appear in the list more than once.<br><span class="badge badge-outline-secondary">READ: Authress:UserPermissions/{userId}</span>
* @summary Get the roles a user has to a resource.
* @param {string} [userId] The user to get roles for.
* @param {string} userId The user to get roles for.
* @param {string} resourceUri The uri path of a resource to get roles for, must be URL encoded. Checks for explicit resource roles, roles attached to parent resources are not returned.
* @throws {ArgumentRequiredError}
*/
// @ts-ignore
getUserRolesForResource(userId?: string | null, resourceUri: string): Promise<Response<UserRoleCollection>>;
getUserRolesForResource(userId: string, resourceUri: string): Promise<Response<UserRoleCollection>>;
/**
* <i class=\"far fa-money-bill-alt text-primary\"></i> <span class=\"text-primary\">Billable</span> 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. To get a user's list of resources in these cases, it is recommended to also check explicit access to the collection resource, using the authorizeUser endpoint. In the case that the user only has access to a subset of resources in a collection, 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 {@link collectionConfiguration} to be {@link collectionConfiguration.INCLUDE_NESTED}. This collection is paginated.
* @summary Get the resources a user has to permission to.
* @param {string} [userId] The user to check permissions on
* @param {string} userId The user to check permissions on
* @param {string} [resourceUri] The top level uri path of a resource to query for. Will only match explicit or collection resource sub-resources. Will not partial match resource names.
* @param {number} [limit] Max number of results to return
* @param {Cursor} [cursor] Continuation cursor for paging (will automatically be set)
Expand All @@ -57,6 +57,6 @@ export interface UserPermissionsApi {
INCLUDE_NESTED - will return all sub-resources as well as deeply nested resources that the user has the specified permission to. A query to resourceUri=Collection will return Collection/namespaces/ns/resources/resource_1. To return matching resources for nested resources, set this parameter to INCLUDE_NESTED.
* @throws {ArgumentRequiredError}
*/
getUserResources(userId?: string | null, resourceUri?: string, limit?: number, cursor?: Cursor, permission?: string, collectionConfiguration?: GetUserResourcesParams.CollectionConfiguration):
getUserResources(userId: string, resourceUri?: string, limit?: number, cursor?: Cursor, permission?: string, collectionConfiguration?: GetUserResourcesParams.CollectionConfiguration):
Promise<Response<UserResources>>;
}
7 changes: 0 additions & 7 deletions src/userPermissions/dtos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,6 @@ export interface UserResources extends IPaginated<UserResources> {
* @memberof UserResources
*/
resources?: Array<UserResourcesResources>;
/**
* If the user has access to all sub-resources, then instead of resources being a list, this property will be populated `true`.
* @type {Array<UserResourcesResources>}
* @memberof UserResources
* @deprecated This property will always be false in later versions. To know if a user has access to all sub-resources, either call {@link authorizerUser} or specify the {@link collectionConfiguration} as {@link collectionConfiguration.INCLUDE_NESTED}.
*/
accessToAllSubResources?: boolean;
}

/**
Expand Down
46 changes: 11 additions & 35 deletions src/userPermissionsApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ class UserPermissionsApi {

async authorizeUser(userId, resourceUri, permission) {
// verify required parameter 'userId' is not null or undefined
let tokenUserId = userId;
if (userId === null || userId === undefined) {
tokenUserId = await getFallbackUser(this.client);
throw new ArgumentRequiredError('userId', 'Required parameter userId was null or undefined when calling authorizeUser.');
}
// verify required parameter 'resourceUri' is not null or undefined
if (resourceUri === null || resourceUri === undefined) {
Expand All @@ -29,91 +28,68 @@ class UserPermissionsApi {
if (permission === null || permission === undefined) {
throw new ArgumentRequiredError('permission', 'Required parameter permission was null or undefined when calling authorizeUser.');
}
const url = `/v1/users/${encodeURIComponent(String(tokenUserId))}/resources/${encodeURIComponent(String(resourceUri))}/permissions/${encodeURIComponent(String(permission))}`;
const url = `/v1/users/${encodeURIComponent(String(userId))}/resources/${encodeURIComponent(String(resourceUri))}/permissions/${encodeURIComponent(String(permission))}`;
try {
const response = await this.client.get(url);
return response;
} catch (error) {
if (error.status === 404) {
throw new UnauthorizedError(tokenUserId, resourceUri, permission);
throw new UnauthorizedError(userId, resourceUri, permission);
}
throw error;
}
}

async disableUserToken(userId, tokenId) {
// verify required parameter 'userId' is not null or undefined
let tokenUserId = userId;
if (userId === null || userId === undefined) {
tokenUserId = await getFallbackUser(this.client);
throw new ArgumentRequiredError('userId', 'Required parameter userId was null or undefined when calling disableUserToken.');
}
// verify required parameter 'tokenId' is not null or undefined
if (tokenId === null || tokenId === undefined) {
throw new ArgumentRequiredError('tokenId', 'Required parameter tokenId was null or undefined when calling disableUserToken.');
}
const url = `/v1/users/${encodeURIComponent(String(tokenUserId))}/tokens/${encodeURIComponent(String(tokenId))}`;
const url = `/v1/users/${encodeURIComponent(String(userId))}/tokens/${encodeURIComponent(String(tokenId))}`;
const response = await this.client.delete(url);
return response;
}

async getUserPermissionsForResource(userId, resourceUri) {
// verify required parameter 'userId' is not null or undefined
let tokenUserId = userId;
if (userId === null || userId === undefined) {
tokenUserId = await getFallbackUser(this.client);
throw new ArgumentRequiredError('userId', 'Required parameter userId was null or undefined when calling getUserPermissionsForResource.');
}
// verify required parameter 'resourceUri' is not null or undefined
if (resourceUri === null || resourceUri === undefined) {
throw new ArgumentRequiredError('resourceUri', 'Required parameter resourceUri was null or undefined when calling getUserPermissionsForResource.');
}

const url = `/v1/users/${encodeURIComponent(String(tokenUserId))}/resources/${encodeURIComponent(String(resourceUri))}/permissions`;
const url = `/v1/users/${encodeURIComponent(String(userId))}/resources/${encodeURIComponent(String(resourceUri))}/permissions`;
const response = await this.client.get(url);
return response;
}

async getUserRolesForResource(userId, resourceUri) {
let tokenUserId = userId;
if (userId === null || userId === undefined) {
tokenUserId = await getFallbackUser(this.client);
throw new ArgumentRequiredError('userId', 'Required parameter userId was null or undefined when calling getUserRolesForResource.');
}
// verify required parameter 'resourceUri' is not null or undefined
if (resourceUri === null || resourceUri === undefined) {
throw new ArgumentRequiredError('resourceUri', 'Required parameter resourceUri was null or undefined when calling getUserRolesForResource.');
}

const url = `/v1/users/${encodeURIComponent(String(tokenUserId))}/resources/${encodeURIComponent(String(resourceUri))}/roles`;
const url = `/v1/users/${encodeURIComponent(String(userId))}/resources/${encodeURIComponent(String(resourceUri))}/roles`;
const response = await this.client.get(url);
return response;
}

async getUserResources(userId, resourceUri, limit, cursor, permission, collectionConfiguration) {
// verify required parameter 'userId' is not null or undefined
let tokenUserId = userId;
if (userId === null || userId === undefined) {
tokenUserId = await getFallbackUser(this.client);
throw new ArgumentRequiredError('userId', 'Required parameter userId was null or undefined when calling getUserResources.');
}

// If just checking the top level or the collectionConfiguration isn't set then assume we need to check for explicit top level.
// * Otherwise we can recurse down using the collectionConfiguration type.
if (!collectionConfiguration || collectionConfiguration === 'TOP_LEVEL_ONLY') {
try {
await this.authorizeUser(userId, resourceUri, permission);
return {
status: 200,
headers: {},
data: {
userId: tokenUserId,
accessToAllSubResources: true,
resources: null
}
};
} catch (error) {
// If the user doesn't have permission to everything, then use the query API.
}
}

const url = new URL(`${this.client.baseUrl}/v1/users/${encodeURIComponent(String(tokenUserId))}/resources`);
const url = new URL(`${this.client.baseUrl}/v1/users/${encodeURIComponent(String(userId))}/resources`);
const qs = { resourceUri };
if (limit) { qs.limit = limit; }
if (cursor) { qs.cursor = cursor; }
Expand Down

0 comments on commit 5479a71

Please sign in to comment.