diff --git a/HopFrame.sln.DotSettings.user b/HopFrame.sln.DotSettings.user index eab4e1d..0d4f6c6 100644 --- a/HopFrame.sln.DotSettings.user +++ b/HopFrame.sln.DotSettings.user @@ -1,4 +1,5 @@  + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -71,6 +72,7 @@ + \ No newline at end of file diff --git a/docs/authentication.md b/docs/authentication.md index 469ceee..f79c51e 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -23,8 +23,6 @@ by configuring your configuration to load these. > `builder.Configuration.AddEnvironmentVariables();` to your startup configuration before you add the > custom configurations / HopFrame services. -### Example - You can specify `Seconds`, `Minutes`, `Hours` and `Days` for either of the two token types. These get combined to a single time span. @@ -49,3 +47,28 @@ HOPFRAME__AUTHENTICATION__ACCESSTOKEN__MINUTES=30 HOPFRAME__AUTHENTICATION__REFRESHTOKEN__DAYS=10 HOPFRAME__AUTHENTICATION__REFRESHTOKEN__HOURS=5 ``` + +## API tokens + +API tokens are useful to use in automation environments that need to access an endpoint or page of your application. +The HopFrame supports this natively and no further configuration is required in order to use them. + +### Create an api token + +You can create an api token via the `ITokenRepository`: +```csharp +tokens.CreateApiToken(user, DateTime.MaxValue); +``` + +This creates a new api token that is valid until the provided DateTime has passed. Note that in the database and the token +model the `CreatedAt` property represents the expiration date on an api token. For security reasons the api token by default +has no permissions. This allows you to create tokens that are just permitted to perform a single action. Note that a token +associated to a user can also have more permissions than the user itself so make sure to properly secure the creation process. + +### Add permissions to an api token + +You can add permissions to an api token like you would to a normal user or group: + +```csharp +permissions.AddPermission(apiToken, "token.permission"); +``` diff --git a/docs/models.md b/docs/models.md index 39ecc99..7f61e86 100644 --- a/docs/models.md +++ b/docs/models.md @@ -35,16 +35,18 @@ public class Permission { public DateTime GrantedAt { get; set; } public virtual User User { get; set; } public virtual PermissionGroup Group { get; set; } + public virtual Token Token { get; set; } } ``` ## Token ```csharp -public class Token { +public class Token : IPermissionOwner { public int Type { get; set; } public Guid Content { get; set; } public DateTime CreatedAt { get; set; } public virtual User Owner { get; set; } + public virtual List Permissions { get; set; } } ``` diff --git a/docs/repositories.md b/docs/repositories.md index 25cb4ac..f72d876 100644 --- a/docs/repositories.md +++ b/docs/repositories.md @@ -71,5 +71,9 @@ public interface ITokenRepository { Task CreateToken(int type, User owner); Task DeleteUserTokens(User owner); + + Task DeleteToken(Token token); + + Task CreateApiToken(User owner, DateTime expirationDate); } ``` diff --git a/tests/HopFrame.Tests.Security/AuthenticationTests.cs b/tests/HopFrame.Tests.Security/AuthenticationTests.cs index 5a00df9..17e3d1d 100644 --- a/tests/HopFrame.Tests.Security/AuthenticationTests.cs +++ b/tests/HopFrame.Tests.Security/AuthenticationTests.cs @@ -43,7 +43,7 @@ public class AuthenticationTests { .ReturnsAsync(correctToken); perms - .Setup(x => x.GetFullPermissions(It.IsAny())) + .Setup(x => x.GetFullPermissions(It.IsAny())) .ReturnsAsync(new List()); var auth = new HopFrameAuthentication(options.Object, logger.Object, encoder.Object, clock.Object, tokens.Object, perms.Object, new OptionsWrapper(new HopFrameAuthenticationOptions())); diff --git a/tests/HopFrame.Tests.Web/AuthMiddlewareTests.cs b/tests/HopFrame.Tests.Web/AuthMiddlewareTests.cs index bada100..685e588 100644 --- a/tests/HopFrame.Tests.Web/AuthMiddlewareTests.cs +++ b/tests/HopFrame.Tests.Web/AuthMiddlewareTests.cs @@ -23,7 +23,7 @@ public class AuthMiddlewareTests { var perms = new Mock(); perms - .Setup(p => p.GetFullPermissions(It.Is(u => newToken.Owner.Id == u.Id))) + .Setup(p => p.GetFullPermissions(It.Is(u => newToken.Owner.Id == u.Owner.Id))) .ReturnsAsync(CreateDummyUser().Permissions.Select(p => p.PermissionName).ToList); return new AuthMiddleware(auth.Object, perms.Object);