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);