/
user.go
71 lines (57 loc) · 1.47 KB
/
user.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
package auth
import (
"errors"
"github.com/labstack/echo/v4"
"github.com/rs/zerolog"
)
const (
// UserKey the key used in the context for the user.
UserKey = "Auth.User"
)
var (
// ErrUserNotFound user not found in context.
ErrUserNotFound = errors.New("user not found in context")
// ErrUserTypeMismatch failed to retrieve user, type mismatch.
ErrUserTypeMismatch = errors.New("failed to retrieve user, type mismatch")
)
// AuthenticatedUser authenticated user used to validate access.
type AuthenticatedUser struct {
ID string `json:"id,omitempty"`
Scopes []string `json:"scopes,omitempty"`
}
// MarshalZerologObject used to print user in logs.
func (au *AuthenticatedUser) MarshalZerologObject(e *zerolog.Event) {
e.Str("id", au.ID).Strs("scopes", au.Scopes)
}
// HasScope check if the authenticated user has one of the allowed
// scopes.
func (au *AuthenticatedUser) HasScope(allowedScopes []string) bool {
if len(allowedScopes) == 0 {
return false
}
// O(n^2)
for _, usc := range au.Scopes {
for _, asc := range allowedScopes {
if usc == asc {
return true
}
}
}
return false
}
// LoadUserFromContext load the authenticated user from the context.
func LoadUserFromContext(ctx echo.Context) (AuthenticatedUser, error) {
var (
user AuthenticatedUser
ok bool
)
uval := ctx.Get(UserKey)
if uval == nil {
return user, ErrUserNotFound
}
user, ok = uval.(AuthenticatedUser)
if !ok {
return user, ErrUserTypeMismatch
}
return user, nil
}