From 56e0e1cc2b4b8b87b9c02b75784075727f64d375 Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Fri, 17 May 2024 09:23:56 +0200 Subject: [PATCH] merge user/current/logins and user/current/login-providers (#16307) also deleted unused requestmodel Co-authored-by: Sven Geusens --- .../GetLinkedLoginsCurrentUserController.cs | 48 ---- .../Users/UsersViewModelsMapDefinition.cs | 9 +- src/Umbraco.Cms.Api.Management/OpenApi.json | 272 +----------------- .../BackOfficeExternalLoginService.cs | 6 +- .../UserExternalLoginProviderResponseModel.cs | 2 + .../ViewModels/User/LinkedLoginViewModel.cs | 8 - .../User/LinkedLoginsRequestModel.cs | 6 - .../Models/UserExternalLoginProviderModel.cs | 5 +- 8 files changed, 17 insertions(+), 339 deletions(-) delete mode 100644 src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetLinkedLoginsCurrentUserController.cs delete mode 100644 src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginViewModel.cs delete mode 100644 src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginsRequestModel.cs diff --git a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetLinkedLoginsCurrentUserController.cs b/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetLinkedLoginsCurrentUserController.cs deleted file mode 100644 index e13e3117bc..0000000000 --- a/src/Umbraco.Cms.Api.Management/Controllers/User/Current/GetLinkedLoginsCurrentUserController.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Asp.Versioning; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Umbraco.Cms.Api.Management.ViewModels.User; -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Mapping; -using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Services.OperationStatus; - -namespace Umbraco.Cms.Api.Management.Controllers.User.Current; - -[ApiVersion("1.0")] -public class GetLinkedLoginsCurrentUserController : CurrentUserControllerBase -{ - private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; - private readonly IUserService _userService; - private readonly IUmbracoMapper _umbracoMapper; - - public GetLinkedLoginsCurrentUserController( - IBackOfficeSecurityAccessor backOfficeSecurityAccessor, - IUserService userService, - IUmbracoMapper umbracoMapper) - { - _backOfficeSecurityAccessor = backOfficeSecurityAccessor; - _userService = userService; - _umbracoMapper = umbracoMapper; - } - - [MapToApiVersion("1.0")] - [HttpGet("logins")] - [ProducesResponseType(typeof(LinkedLoginsRequestModel), StatusCodes.Status200OK)] - public async Task GetLinkedLogins(CancellationToken cancellationToken) - { - Guid currentUserKey = CurrentUserKey(_backOfficeSecurityAccessor); - - Attempt, UserOperationStatus> linkedLoginsAttempt = await _userService.GetLinkedLoginsAsync(currentUserKey); - - if (linkedLoginsAttempt.Success == false) - { - return UserOperationStatusResult(linkedLoginsAttempt.Status); - } - - List models = _umbracoMapper.MapEnumerable(linkedLoginsAttempt.Result); - - return Ok(new LinkedLoginsRequestModel { LinkedLogins = models }); - } -} diff --git a/src/Umbraco.Cms.Api.Management/Mapping/Users/UsersViewModelsMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/Users/UsersViewModelsMapDefinition.cs index 63213000e1..df31b0ccad 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/Users/UsersViewModelsMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/Users/UsersViewModelsMapDefinition.cs @@ -14,18 +14,10 @@ public class UsersViewModelsMapDefinition : IMapDefinition { mapper.Define((_, _) => new ResetPasswordUserResponseModel(), Map); mapper.Define((_, _) => new CreateUserResponseModel { User = new() }, Map); - mapper.Define((_, _) => new LinkedLoginViewModel { ProviderKey = string.Empty, ProviderName = string.Empty }, Map); mapper.Define( (_, _) => new UserExternalLoginProviderResponseModel { ProviderSchemeName = string.Empty }, Map); } - // Umbraco.Code.MapAll - private void Map(IIdentityUserLogin source, LinkedLoginViewModel target, MapperContext context) - { - target.ProviderKey = source.ProviderKey; - target.ProviderName = source.LoginProvider; - } - // Umbraco.Code.MapAll private void Map(UserCreationResult source, CreateUserResponseModel target, MapperContext context) { @@ -48,5 +40,6 @@ public class UsersViewModelsMapDefinition : IMapDefinition target.ProviderSchemeName = source.ProviderSchemeName; target.HasManualLinkingEnabled = source.HasManualLinkingEnabled; target.IsLinkedOnUser = source.IsLinkedOnUser; + target.ProviderKey = source.ProviderKey; } } diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index 3826879398..8263fe9a2f 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -19524,205 +19524,6 @@ ] } }, - "/umbraco/management/api/v1/my/item": { - "post": { - "tags": [ - "My item API" - ], - "parameters": [ - { - "name": "value", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - }, - "get": { - "tags": [ - "My item API" - ], - "parameters": [ - { - "name": "skip", - "in": "query", - "schema": { - "type": "integer", - "format": "int32", - "default": 0 - } - }, - { - "name": "take", - "in": "query", - "schema": { - "type": "integer", - "format": "int32", - "default": 10 - } - } - ], - "responses": { - "200": { - "description": "Success" - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - } - }, - "/umbraco/management/api/v1/my/item/{id}": { - "delete": { - "tags": [ - "My item API" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "200": { - "description": "Success", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - }, - "get": { - "tags": [ - "My item API" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } - ], - "responses": { - "200": { - "description": "Success" - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - }, - "put": { - "tags": [ - "My item API" - ], - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "value", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "Success", - "headers": { - "Umb-Notifications": { - "description": "The list of notifications produced during the request.", - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationHeaderModel" - }, - "nullable": true - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - } - }, "/umbraco/management/api/v1/object-types": { "get": { "tags": [ @@ -30937,38 +30738,6 @@ ] } }, - "/umbraco/management/api/v1/user/current/logins": { - "get": { - "tags": [ - "User" - ], - "operationId": "GetUserCurrentLogins", - "responses": { - "200": { - "description": "Success", - "content": { - "application/json": { - "schema": { - "oneOf": [ - { - "$ref": "#/components/schemas/LinkedLoginsRequestModel" - } - ] - } - } - } - }, - "401": { - "description": "The resource is protected and requires an authentication token" - } - }, - "security": [ - { - "Backoffice User": [ ] - } - ] - } - }, "/umbraco/management/api/v1/user/current/permissions": { "get": { "tags": [ @@ -37313,41 +37082,6 @@ }, "additionalProperties": false }, - "LinkedLoginModel": { - "required": [ - "providerKey", - "providerName" - ], - "type": "object", - "properties": { - "providerName": { - "type": "string" - }, - "providerKey": { - "type": "string" - } - }, - "additionalProperties": false - }, - "LinkedLoginsRequestModel": { - "required": [ - "linkedLogins" - ], - "type": "object", - "properties": { - "linkedLogins": { - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/LinkedLoginModel" - } - ] - } - } - }, - "additionalProperties": false - }, "LogLevelCountsReponseModel": { "required": [ "debug", @@ -43841,6 +43575,10 @@ "providerSchemeName": { "type": "string" }, + "providerKey": { + "type": "string", + "nullable": true + }, "isLinkedOnUser": { "type": "boolean" }, @@ -44476,4 +44214,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/Umbraco.Cms.Api.Management/Services/BackOfficeExternalLoginService.cs b/src/Umbraco.Cms.Api.Management/Services/BackOfficeExternalLoginService.cs index 3bed9791c7..9f7fec03d4 100644 --- a/src/Umbraco.Cms.Api.Management/Services/BackOfficeExternalLoginService.cs +++ b/src/Umbraco.Cms.Api.Management/Services/BackOfficeExternalLoginService.cs @@ -53,12 +53,16 @@ public class BackOfficeExternalLoginService : IBackOfficeExternalLoginService Enumerable.Empty()); } + // The use of SingleOrDefault below is allowed as there is a unique index on the linkedLogins result between user and provider IEnumerable providerStatuses = providers.Select( providerScheme => new UserExternalLoginProviderModel( providerScheme.ExternalLoginProvider.AuthenticationType, linkedLoginsAttempt.Result.Any(linkedLogin => linkedLogin.LoginProvider == providerScheme.ExternalLoginProvider.AuthenticationType), - providerScheme.ExternalLoginProvider.Options.AutoLinkOptions.AllowManualLinking)); + providerScheme.ExternalLoginProvider.Options.AutoLinkOptions.AllowManualLinking, + linkedLoginsAttempt.Result.SingleOrDefault(linkedLogin => + linkedLogin.LoginProvider == providerScheme.ExternalLoginProvider.AuthenticationType) + ?.ProviderKey)); return Attempt, ExternalLoginOperationStatus>.Succeed( ExternalLoginOperationStatus.Success, providerStatuses); diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/User/Current/UserExternalLoginProviderResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/User/Current/UserExternalLoginProviderResponseModel.cs index edca47ce90..cbb30177db 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/User/Current/UserExternalLoginProviderResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/User/Current/UserExternalLoginProviderResponseModel.cs @@ -7,4 +7,6 @@ public class UserExternalLoginProviderResponseModel public bool IsLinkedOnUser { get; set; } public bool HasManualLinkingEnabled { get; set; } + + public string? ProviderKey { get; set; } } diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginViewModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginViewModel.cs deleted file mode 100644 index df811eabfb..0000000000 --- a/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginViewModel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.User; - -public class LinkedLoginViewModel -{ - public required string ProviderName { get; set; } - - public required string ProviderKey { get; set; } -} diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginsRequestModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginsRequestModel.cs deleted file mode 100644 index 11155ff48d..0000000000 --- a/src/Umbraco.Cms.Api.Management/ViewModels/User/LinkedLoginsRequestModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.User; - -public class LinkedLoginsRequestModel -{ - public IEnumerable LinkedLogins { get; set; } = Enumerable.Empty(); -} diff --git a/src/Umbraco.Core/Models/UserExternalLoginProviderModel.cs b/src/Umbraco.Core/Models/UserExternalLoginProviderModel.cs index 2f5d48fd78..538012245d 100644 --- a/src/Umbraco.Core/Models/UserExternalLoginProviderModel.cs +++ b/src/Umbraco.Core/Models/UserExternalLoginProviderModel.cs @@ -2,15 +2,18 @@ namespace Umbraco.Cms.Core.Models; public class UserExternalLoginProviderModel { - public UserExternalLoginProviderModel(string providerSchemeName, bool isLinkedOnUser, bool hasManualLinkingEnabled) + public UserExternalLoginProviderModel(string providerSchemeName, bool isLinkedOnUser, bool hasManualLinkingEnabled, string? providerKey) { ProviderSchemeName = providerSchemeName; IsLinkedOnUser = isLinkedOnUser; HasManualLinkingEnabled = hasManualLinkingEnabled; + ProviderKey = providerKey; } public string ProviderSchemeName { get; } + public string? ProviderKey { get; set; } + public bool IsLinkedOnUser { get; } public bool HasManualLinkingEnabled { get; }