-
Notifications
You must be signed in to change notification settings - Fork 0
/
user.go
117 lines (95 loc) · 3.36 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
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
/*
Copyright (C) 2016-2017 Contributors as noted in the AUTHORS file
This file is part of lara, veterinary practice support software.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package lara
import (
"context"
"fmt"
)
// -----------------------------------------------------------------------------
// USER MANAGEMENT SERVICE
// User is application user
type User struct {
Login string
Permissions map[PermissionType]bool // map instead of slice, for fast searching
}
// MakeUser creates User from login and list of permissions
func MakeUser(login string, permissions []string) (u *User, err error) {
u = &User{Login: login}
u.Permissions, err = MakePermissions(permissions)
return
}
// MakePermissions converts string slice to PermissionType set
func MakePermissions(perms []string) (map[PermissionType]bool, error) {
result := make(map[PermissionType]bool)
for _, s := range perms {
var p PermissionType
if err := p.FromString(s); err != nil {
return nil, err
}
result[p] = true
}
return result, nil
}
// PermissionType defines user's permission
//go:generate stringer -type=PermissionType -output permission_string.go
//requires golang.org/x/tools/cmd/stringer installed locally
//if new object permission added to enum, run "go generate"
type PermissionType int
// Permission types enum
const (
ViewRecord PermissionType = iota
EditRecord
ViewReports
EditProducts
)
// FromString creates PermissionType from string
func (i *PermissionType) FromString(perm string) error {
// TODO: more intelligent implementation
switch perm {
case "ViewRecord":
*i = ViewRecord
case "EditRecord":
*i = EditRecord
case "ViewReports":
*i = ViewReports
case "EditProducts":
*i = EditProducts
default:
return fmt.Errorf("bad PermissionType: '%s'", perm)
}
return nil
}
// DefaultPermissions is set of default permissions for new user
var DefaultPermissions = []PermissionType{ViewRecord}
// UserService manages application's users
type UserService interface {
Authenticate(ctx context.Context, login, password string) (*User, error)
Register(ctx context.Context, login, password string, permissions []PermissionType) error
Grant(ctx context.Context, login string, permissions []PermissionType) error
Revoke(ctx context.Context, login string, permissions []PermissionType) error
}
// -----------------------------------------------------------------------------
// User in Context
type keyType int
const userKey keyType = 0
// ContextWithUser returns a new Context that carries User u.
func ContextWithUser(ctx context.Context, u *User) context.Context {
return context.WithValue(ctx, userKey, u)
}
// UserFromContext returns the User value stored in ctx, if any.
func UserFromContext(ctx context.Context) (*User, bool) {
u, ok := ctx.Value(userKey).(*User)
return u, ok
}