merge user/current/logins and user/current/login-providers (#16307)

also deleted unused requestmodel

Co-authored-by: Sven Geusens <sge@umbraco.dk>
This commit is contained in:
Sven Geusens
2024-05-17 09:23:56 +02:00
committed by GitHub
parent 295f6f8720
commit 56e0e1cc2b
8 changed files with 17 additions and 339 deletions

View File

@@ -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<IActionResult> GetLinkedLogins(CancellationToken cancellationToken)
{
Guid currentUserKey = CurrentUserKey(_backOfficeSecurityAccessor);
Attempt<ICollection<IIdentityUserLogin>, UserOperationStatus> linkedLoginsAttempt = await _userService.GetLinkedLoginsAsync(currentUserKey);
if (linkedLoginsAttempt.Success == false)
{
return UserOperationStatusResult(linkedLoginsAttempt.Status);
}
List<LinkedLoginViewModel> models = _umbracoMapper.MapEnumerable<IIdentityUserLogin, LinkedLoginViewModel>(linkedLoginsAttempt.Result);
return Ok(new LinkedLoginsRequestModel { LinkedLogins = models });
}
}

View File

@@ -14,18 +14,10 @@ public class UsersViewModelsMapDefinition : IMapDefinition
{
mapper.Define<PasswordChangedModel, ResetPasswordUserResponseModel>((_, _) => new ResetPasswordUserResponseModel(), Map);
mapper.Define<UserCreationResult, CreateUserResponseModel>((_, _) => new CreateUserResponseModel { User = new() }, Map);
mapper.Define<IIdentityUserLogin, LinkedLoginViewModel>((_, _) => new LinkedLoginViewModel { ProviderKey = string.Empty, ProviderName = string.Empty }, Map);
mapper.Define<UserExternalLoginProviderModel, UserExternalLoginProviderResponseModel>(
(_, _) => 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;
}
}

View File

@@ -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 @@
}
}
}
}
}

View File

@@ -53,12 +53,16 @@ public class BackOfficeExternalLoginService : IBackOfficeExternalLoginService
Enumerable.Empty<UserExternalLoginProviderModel>());
}
// The use of SingleOrDefault below is allowed as there is a unique index on the linkedLogins result between user and provider
IEnumerable<UserExternalLoginProviderModel> 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<IEnumerable<UserExternalLoginProviderModel>, ExternalLoginOperationStatus>.Succeed(
ExternalLoginOperationStatus.Success, providerStatuses);

View File

@@ -7,4 +7,6 @@ public class UserExternalLoginProviderResponseModel
public bool IsLinkedOnUser { get; set; }
public bool HasManualLinkingEnabled { get; set; }
public string? ProviderKey { get; set; }
}

View File

@@ -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; }
}

View File

@@ -1,6 +0,0 @@
namespace Umbraco.Cms.Api.Management.ViewModels.User;
public class LinkedLoginsRequestModel
{
public IEnumerable<LinkedLoginViewModel> LinkedLogins { get; set; } = Enumerable.Empty<LinkedLoginViewModel>();
}

View File

@@ -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; }