-
Notifications
You must be signed in to change notification settings - Fork 18
/
users-manager.go
128 lines (113 loc) · 3.95 KB
/
users-manager.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
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
* SPDX-License-Identifier: MIT
*/
package users
import (
"context"
"encoding/json"
"fmt"
"hash/fnv"
"github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/contexts"
"github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/managers"
"github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability"
observ_utils "github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/observability/utils"
"github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/providers"
"github.com/eclipse-symphony/symphony/coa/pkg/apis/v1alpha2/providers/states"
"github.com/eclipse-symphony/symphony/coa/pkg/logger"
)
var log = logger.NewLogger("coa.runtime")
type UsersManager struct {
managers.Manager
StateProvider states.IStateProvider
}
type UserState struct {
Id string `json:"id"`
PasswordHash string `json:"passwordHash,omitempty"`
Roles []string `json:"roles,omitempty"`
}
func (s *UsersManager) Init(context *contexts.VendorContext, config managers.ManagerConfig, providers map[string]providers.IProvider) error {
stateprovider, err := managers.GetStateProvider(config, providers)
if err == nil {
s.StateProvider = stateprovider
} else {
log.Errorf(" M (Users): failed to get state provider %+v", err)
return err
}
return nil
}
func (t *UsersManager) DeleteUser(ctx context.Context, name string) error {
ctx, span := observability.StartSpan("Users Manager", ctx, &map[string]string{
"method": "DeleteUser",
})
var err error = nil
defer observ_utils.CloseSpanWithError(span, &err)
log.Infof(" M (Users): DeleteUser name %s, traceId: %s", name, span.SpanContext().TraceID().String())
err = t.StateProvider.Delete(ctx, states.DeleteRequest{
ID: name,
})
if err != nil {
log.Debugf(" M (Users) : failed to delete user %s, traceId: %s", err, span.SpanContext().TraceID().String())
return err
}
return nil
}
func hash(name string, s string) string {
h := fnv.New32a()
h.Write([]byte(name + "." + s + ".salt"))
return fmt.Sprintf("H%d", h.Sum32())
}
func (t *UsersManager) UpsertUser(ctx context.Context, name string, password string, roles []string) error {
ctx, span := observability.StartSpan("Users Manager", ctx, &map[string]string{
"method": "UpsertUser",
})
var err error = nil
defer observ_utils.CloseSpanWithError(span, &err)
log.Infof(" M (Users): UpsertUser name %s, traceId: %s", name, span.SpanContext().TraceID().String())
upsertRequest := states.UpsertRequest{
Value: states.StateEntry{
ID: name,
Body: UserState{
Id: name,
PasswordHash: hash(name, password),
Roles: roles,
},
},
}
_, err = t.StateProvider.Upsert(ctx, upsertRequest)
if err != nil {
log.Debugf(" M (Users) : failed to upsert user %v, traceId: %s", err, span.SpanContext().TraceID().String())
return err
}
return nil
}
func (t *UsersManager) CheckUser(ctx context.Context, name string, password string) ([]string, bool) {
ctx, span := observability.StartSpan("Users Manager", ctx, &map[string]string{
"method": "CheckUser",
})
var err error = nil
defer observ_utils.CloseSpanWithError(span, &err)
log.Infof(" M (Users): CheckUser name %s, traceId: %s", name, span.SpanContext().TraceID().String())
getRequest := states.GetRequest{
ID: name,
}
var user states.StateEntry
user, err = t.StateProvider.Get(ctx, getRequest)
if err != nil {
log.Debugf(" M (Users) : failed to get user %s states, traceId: %s", err, span.SpanContext().TraceID().String())
return nil, false
}
var userState UserState
bytes, _ := json.Marshal(user.Body)
err = json.Unmarshal(bytes, &userState)
if err != nil {
return nil, false
}
if hash(name, password) == userState.PasswordHash {
log.Debugf(" M (Users) : user authenticated, traceId: %s", span.SpanContext().TraceID().String())
return userState.Roles, true
}
log.Debugf(" M (Users) : authentication failed, traceId: %s", span.SpanContext().TraceID().String())
return nil, false
}