API access with client credentials (core functionality) (#16817)
* First stab * Delivery API client credentials + a little refactor to ensure unique client IDs * Introduce user type * Support user type in the Management API * Clean up TODOs * Update API user last login date when issuing a token * Better error reporting for mismatched user types * Do not allow password change or reset for API users * Update OpenApi.json * Revert change * Remove obsolete comment * Make applicable classes abstract or sealed * Review changes * Add endpoint for retrieving all user client IDs
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Membership;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
|
||||
|
||||
public partial class UserServiceCrudTests
|
||||
{
|
||||
[Test]
|
||||
public async Task Can_Reset_Password()
|
||||
{
|
||||
var securitySettings = new SecuritySettings();
|
||||
var userService = CreateUserService(securitySettings);
|
||||
|
||||
var userGroup = await UserGroupService.GetAsync(Constants.Security.AdminGroupAlias);
|
||||
var creationModel = new UserCreateModel
|
||||
{
|
||||
UserName = "some@one",
|
||||
Email = "some@one",
|
||||
Name = "Some One",
|
||||
UserGroupKeys = new HashSet<Guid> { userGroup.Key }
|
||||
};
|
||||
|
||||
var userKey = (await userService.CreateAsync(Constants.Security.SuperUserKey, creationModel, true)).Result.CreatedUser!.Key;
|
||||
|
||||
var result = await userService.ResetPasswordAsync(Constants.Security.SuperUserKey, userKey);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(UserOperationStatus.Success, result.Status);
|
||||
Assert.IsNotNull(result.Result.ResetPassword);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Reset_Password_For_Api_User()
|
||||
{
|
||||
var securitySettings = new SecuritySettings();
|
||||
var userService = CreateUserService(securitySettings);
|
||||
|
||||
var userGroup = await UserGroupService.GetAsync(Constants.Security.AdminGroupAlias);
|
||||
var creationModel = new UserCreateModel
|
||||
{
|
||||
UserName = "some@one",
|
||||
Email = "some@one",
|
||||
Name = "Some One",
|
||||
UserGroupKeys = new HashSet<Guid> { userGroup.Key },
|
||||
Type = UserType.Api
|
||||
};
|
||||
|
||||
var userKey = (await userService.CreateAsync(Constants.Security.SuperUserKey, creationModel, true)).Result.CreatedUser!.Key;
|
||||
|
||||
var result = await userService.ResetPasswordAsync(Constants.Security.SuperUserKey, userKey);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(UserOperationStatus.InvalidUserType, result.Status);
|
||||
Assert.IsNull(result.Result.ResetPassword);
|
||||
Assert.IsNull(result.Exception);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,37 @@ public partial class UserServiceCrudTests
|
||||
Assert.IsNotNull(createdUser);
|
||||
Assert.AreEqual(username, createdUser.Username);
|
||||
Assert.AreEqual(email, createdUser.Email);
|
||||
Assert.AreEqual(UserType.Default, createdUser.Type);
|
||||
}
|
||||
|
||||
[TestCase(UserType.Default)]
|
||||
[TestCase(UserType.Api)]
|
||||
public async Task Can_Create_All_User_Types(UserType type)
|
||||
{
|
||||
var securitySettings = new SecuritySettings();
|
||||
var userService = CreateUserService(securitySettings);
|
||||
|
||||
var userGroup = await UserGroupService.GetAsync(Constants.Security.AdminGroupAlias);
|
||||
var creationModel = new UserCreateModel
|
||||
{
|
||||
UserName = "api@local",
|
||||
Email = "api@local",
|
||||
Name = "API user",
|
||||
UserGroupKeys = new HashSet<Guid> { userGroup.Key },
|
||||
Type = type
|
||||
};
|
||||
|
||||
var result = await userService.CreateAsync(Constants.Security.SuperUserKey, creationModel, true);
|
||||
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(UserOperationStatus.Success, result.Status);
|
||||
var createdUser = result.Result.CreatedUser;
|
||||
Assert.IsNotNull(createdUser);
|
||||
Assert.AreEqual(type, createdUser.Type);
|
||||
|
||||
var user = await userService.GetAsync(createdUser.Key);
|
||||
Assert.NotNull(user);
|
||||
Assert.AreEqual(type, user.Type);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
Reference in New Issue
Block a user