/* * Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.CognitoIdentityProvider; using Amazon.CognitoIdentityProvider.Model; using Amazon.Extensions.CognitoAuthentication; using Microsoft.AspNetCore.Identity; using System; using System.Threading; using System.Threading.Tasks; namespace Amazon.AspNetCore.Identity.Cognito { public class CognitoRoleStore : IRoleStore where TRole : CognitoRole { private IAmazonCognitoIdentityProvider _cognitoClient; private CognitoUserPool _pool; public CognitoRoleStore(IAmazonCognitoIdentityProvider cognitoClient, CognitoUserPool pool) { _cognitoClient = cognitoClient ?? throw new ArgumentNullException(nameof(cognitoClient)); _pool = pool ?? throw new ArgumentNullException(nameof(pool)); } /// /// Creates a new role in the store as an asynchronous operation. /// /// The role to create in the store. /// A that represents the of the asynchronous query. public virtual async Task CreateAsync(TRole role, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (role == null) { throw new ArgumentNullException(nameof(role)); } await _cognitoClient.CreateGroupAsync(new CreateGroupRequest() { Description = role.Description, GroupName = role.Name, Precedence = role.Precedence, RoleArn = role.RoleArn, UserPoolId = _pool.PoolID }, cancellationToken).ConfigureAwait(false); return IdentityResult.Success; } /// /// Deletes a role from the store as an asynchronous operation. /// /// The role to delete from the store. /// A that represents the of the asynchronous query. public virtual async Task DeleteAsync(TRole role, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (role == null) { throw new ArgumentNullException(nameof(role)); } await _cognitoClient.DeleteGroupAsync(new DeleteGroupRequest() { GroupName = role.Name, UserPoolId = _pool.PoolID }, cancellationToken).ConfigureAwait(false); return IdentityResult.Success; } /// /// Finds the role that has the specified normalized name as an asynchronous operation. /// /// The role name to look for. /// A that represents the result of the look up. public virtual async Task FindByNameAsync(string roleName, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var response = await _cognitoClient.GetGroupAsync(new GetGroupRequest() { GroupName = roleName, UserPoolId = _pool.PoolID }, cancellationToken).ConfigureAwait(false); return new CognitoRole(response.Group.GroupName, response.Group.Description, response.Group.Precedence, response.Group.RoleArn) as TRole; } /// /// Updates a role in a store as an asynchronous operation. /// /// The role to update in the store. /// A that represents the of the asynchronous query. public virtual async Task UpdateAsync(TRole role, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (role == null) { throw new ArgumentNullException(nameof(role)); } await _cognitoClient.UpdateGroupAsync(new UpdateGroupRequest() { Description = role.Description, GroupName = role.Name, Precedence = role.Precedence, RoleArn = role.RoleArn, UserPoolId = _pool.PoolID }, cancellationToken).ConfigureAwait(false); return IdentityResult.Success; } /// /// Gets the name of a role as an asynchronous operation. /// /// The role whose name should be returned. /// A that contains the name of the role. public virtual Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken) { return Task.FromResult(role.Name); } /// /// Sets the name of a role in the store as an asynchronous operation. /// This is currently not supported as changing a role name is not supported by Cognito. /// /// The role whose name should be set. /// The name of the role. /// The that represents the asynchronous operation. public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken) { throw new NotSupportedException("Changing role names in not supported."); } /// /// Gets the ID for a role from the store as an asynchronous operation. /// This is currently not supported as Cognito does not expose role ids. /// Use GetRoleNameAsync() instead. /// /// The role whose ID should be returned. /// A that contains the ID of the role. public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken) { throw new NotSupportedException("Cognito does not expose role ids, use GetRoleNameAsync() instead"); } /// /// Finds the role that has the specified ID as an asynchronous operation. /// This is currently not supported as Cognito does not expose role ids. /// Use FindByNameAsync() instead. /// /// The role ID to look for. /// A that result of the look up. public Task FindByIdAsync(string roleId, CancellationToken cancellationToken) { throw new NotSupportedException("Cognito does not expose role ids, use FindByNameAsync() instead"); } /// /// Set a role's normalized name as an asynchronous operation. /// This is currently not supported as Cognito is case-sensitive and does not support normalized role names. /// Use SetRoleNameAsync() instead. /// /// The role whose normalized name should be set. /// The normalized name to set /// The that represents the asynchronous operation. public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken) { throw new NotSupportedException("Cognito is case-sensitive and does not support normalized role names. Use SetRoleNameAsync() instead"); } /// /// Get a role's normalized name as an asynchronous operation. /// This is currently not supported as Cognito is case-sensitive and does not support normalized role names. /// Use GetRoleNameAsync() instead. /// /// The role whose normalized name should be retrieved. /// A that contains the name of the role. public Task GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken) { throw new NotSupportedException("Cognito is case-sensitive and does not support normalized role names. Use GetRoleNameAsync() instead"); } #region IDisposable private bool disposed = false; protected virtual void Dispose(bool disposing) { if (disposed) return; disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } #endregion } }