/
UAuth.go
151 lines (119 loc) · 3.82 KB
/
UAuth.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package uauth
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"time"
"github.com/dunv/ulog"
"github.com/dunv/umongo"
"go.mongodb.org/mongo-driver/mongo"
)
// TODO: add logging lib-config
var packageConfig Config
func SetConfig(_config Config) error {
packageConfig = _config
if packageConfig.UHTTP == nil {
return errors.New("UHTTP needs to be set in config")
}
mongoClient, _, err := umongo.NewDbClient(_config.UserDbConnectionString, fmt.Sprintf("uauth_%s", _config.TokenIssuer), time.Second)
if err != nil {
return fmt.Errorf("Could not connect to db. Exiting (%v)", err)
}
userService := NewUserService(mongoClient, _config.UserDbName)
if err := packageConfig.UHTTP.AddContext(CtxKeyUserService, userService); err != nil {
return err
}
roleService := NewRoleService(mongoClient, _config.UserDbName)
if err := packageConfig.UHTTP.AddContext(CtxKeyRoleService, roleService); err != nil {
return err
}
if err := packageConfig.UHTTP.AddContext(CtxKeyUserDbClient, mongoClient); err != nil {
return err
}
if err := packageConfig.UHTTP.AddContext(CtxKeyConfig, &_config); err != nil {
return err
}
if err := packageConfig.UHTTP.AddContext(CtxKeyUserDbName, _config.UserDbName); err != nil {
return err
}
if err := CreateInitialRolesIfNotExist(mongoClient, _config.UserDbName); err != nil {
return err
}
if err := CreateInitialUsersIfNotExist(mongoClient, _config.UserDbName); err != nil {
return err
}
if len(_config.WantedRoles) > 0 {
err := CreateCustomRolesIfNotExist(mongoClient, _config.UserDbName, _config.WantedRoles, _config.TokenIssuer)
if err != nil {
return err
}
}
return nil
}
func UserFromContext(ctx context.Context, additionalAttributes ...interface{}) (*User, error) {
var user User
var ok bool
if user, ok = ctx.Value(CtxKeyUser).(User); !ok {
return nil, errors.New("could not find user in request context")
}
if len(additionalAttributes) == 1 && additionalAttributes[0] != nil {
bytes, err := json.Marshal(user.AdditionalAttributes)
if err != nil {
return nil, fmt.Errorf("could not marshal additionalAttributes (%s)", err)
}
err = json.Unmarshal(bytes, additionalAttributes[0])
if err != nil {
return nil, fmt.Errorf("could not unmarshal additionalAttributes (%s)", err)
}
}
return &user, nil
}
func GetUserService(r *http.Request) *UserService {
return r.Context().Value(CtxKeyUserService).(*UserService)
}
func GetRoleService(r *http.Request) *RoleService {
return r.Context().Value(CtxKeyRoleService).(*RoleService)
}
func UserFromRequest(r *http.Request, additionalAttributes ...interface{}) (*User, error) {
return UserFromContext(r.Context(), additionalAttributes...)
}
func GenericUserFromRequest(r *http.Request) interface{} {
return r.Context().Value(CtxKeyUser)
}
func UserDB(r *http.Request) *mongo.Client {
if user, ok := r.Context().Value(CtxKeyUserDbClient).(*mongo.Client); ok {
return user
}
ulog.Errorf("could not find userDB in request context")
return nil
}
func UserDBName(r *http.Request) string {
if userDbName, ok := r.Context().Value(CtxKeyUserDbName).(string); ok {
return userDbName
}
ulog.Errorf("could not find userDbName in request context")
return ""
}
func IsAuthBasic(r *http.Request) bool {
return IsAuthMethod("basic", r)
}
func IsAuthJWT(r *http.Request) bool {
return IsAuthMethod("jwt", r)
}
func IsAuthMethod(authMethod string, r *http.Request) bool {
if r.Context().Value(CtxKeyAuthMethod) != nil && r.Context().Value(CtxKeyAuthMethod) == authMethod {
return true
}
return false
}
func ConfigFromRequest(r *http.Request) (*Config, error) {
return ConfigFromContext(r.Context())
}
func ConfigFromContext(ctx context.Context) (*Config, error) {
if ctx.Value(CtxKeyConfig) != nil {
return ctx.Value(CtxKeyConfig).(*Config), nil
}
return nil, errors.New("could not find config in request context")
}