-
Notifications
You must be signed in to change notification settings - Fork 0
/
opsAuth.go
73 lines (63 loc) · 2.79 KB
/
opsAuth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package wildlifenl
import (
"context"
"net/http"
"github.com/UtrechtUniversity/wildlifenl/models"
"github.com/danielgtaylor/huma/v2"
)
type authOperations Operations
func newAuthOperations() *authOperations {
return &authOperations{Endpoint: "auth"}
}
type AuthenticationInput struct {
Body struct {
DisplayNameApp string `json:"displayNameApp" doc:"The display name of the requesting app, will be used in the email message." example:"MyApp"`
Email string `json:"email" doc:"The email address that the authentication code should be send to." format:"email"`
}
}
type AuthenticationResult struct {
Body string `json:"message"`
}
func (o *authOperations) RegisterAuthentication(api huma.API) {
name := "Authenticate"
description := "Start the login process and request a code by email, then call Authorize with this code."
path := "/" + o.Endpoint + "/"
scopes := []string{}
method := http.MethodPost
huma.Register(api, huma.Operation{
OperationID: name, Summary: name, Path: path, Method: method, Tags: []string{o.Endpoint}, Description: generateDescription(description, scopes), Security: []map[string][]string{{"": scopes}},
}, func(ctx context.Context, input *AuthenticationInput) (*AuthenticationResult, error) {
if err := authenticate(input.Body.DisplayNameApp, input.Body.Email); err != nil {
return nil, handleError(err)
}
return &AuthenticationResult{Body: "The authentication code has been sent to: " + input.Body.Email}, nil
})
}
type AuthorizationInput struct {
Body struct {
Email string `json:"email" doc:"The email address that the authentication process was started with." format:"email"`
Code string `json:"code" doc:"The code as received by email." example:"123456"`
}
}
type AuthorizationResult struct {
Body *models.Credential `json:"credential"`
}
func (o *authOperations) RegisterAuthorisation(api huma.API) {
name := "Authorize"
description := "Finalize the login process by providing the code as received by email and get a bearer token."
path := "/" + o.Endpoint + "/"
scopes := []string{}
method := http.MethodPut
huma.Register(api, huma.Operation{
OperationID: name, Summary: name, Path: path, Method: method, Tags: []string{o.Endpoint}, Description: generateDescription(description, scopes), Security: []map[string][]string{{"": scopes}},
}, func(ctx context.Context, input *AuthorizationInput) (*AuthorizationResult, error) {
credential, err := authorize(input.Body.Email, input.Body.Code)
if err != nil {
return nil, handleError(err)
}
if credential == nil {
return nil, huma.Error403Forbidden("The combination of email and code does not match a previous authentication. If you are sure that the email is correct, perhaps the code expired. You can authenticate again to get a new code.")
}
return &AuthorizationResult{Body: credential}, nil
})
}