This repository has been archived by the owner on Sep 8, 2018. It is now read-only.
/
scopes.go
135 lines (111 loc) · 3.6 KB
/
scopes.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
package data
import (
"fmt"
"golang.org/x/crypto/bcrypt"
)
// ScopeUser is a hierarchy of a user and the resource and role
// scopes they have been assigned
type ScopeUser struct {
ID string
Name string
Description string
ScopeResources []ScopeResource
}
// ScopeResource is part of the user/resource/role scope hierarchy
type ScopeResource struct {
ID string
Name string
Description string
ScopeRoles []ScopeRole
}
// ScopeRole is part of the user/resource/role scope hierarchy
type ScopeRole struct {
ID string
Name string
Description string
}
// GetUserScopesWithCredentials - verifies credentials and returns the scopeuser hierarchy
func (store DBManager) GetUserScopesWithCredentials(name, secret string) (ScopeUser, error) {
retUser := ScopeUser{}
// First, find the user with the given name and get the hashed password
user := User{}
err := store.systemdb.QueryRow("SELECT id, enabled, name, description, secrethash, created, createdby, updated, updatedby, deleted, deletedby FROM user WHERE name=$1;", name).Scan(
&user.ID,
&user.Enabled,
&user.Name,
&user.Description,
&user.SecretHash,
&user.Created,
&user.CreatedBy,
&user.Updated,
&user.UpdatedBy,
&user.Deleted,
&user.DeletedBy,
)
if err != nil {
return retUser, fmt.Errorf("Problem selecting user: %s", err)
}
// Compare the given password with the hash
err = bcrypt.CompareHashAndPassword([]byte(user.SecretHash), []byte(secret))
if err != nil { // nil means it is a match
return retUser, fmt.Errorf("The user was not found or the password was incorrect")
}
// If everything checks out, get the scopeuser information and return it:
retUser, err = store.getUserScopes(user)
if err != nil {
return retUser, fmt.Errorf("Problem fetching scopes for the user: %s", err)
}
// Return our user:
return retUser, nil
}
// getUserScopes gets the scope hierarchy for a given user
func (store DBManager) getUserScopes(user User) (ScopeUser, error) {
// First, copy the necessary properties from the passed user
retval := ScopeUser{
ID: user.ID,
Name: user.Name,
Description: user.Description,
}
// Next, look in the user_resource_role table:
// -- see what resources they have
// -- see what roles they have on those resources
// Build up the ScopeUser hierarchy
rows, err := store.systemdb.Query(getResourcesForUser, user.ID)
if err != nil {
return retval, fmt.Errorf("Problem getting resources for user %s / %v: %s", user.Name, user.ID, err)
}
for rows.Next() {
gres := ScopeResource{}
if err = rows.Scan(
&gres.ID,
&gres.Name,
&gres.Description); err != nil {
rows.Close()
break
}
// Now that we have a resource, see what roles we should add to it for this user:
rolesrows, err := store.systemdb.Query(getRolesForUserAndResources, user.ID, gres.ID)
if err != nil {
return retval, fmt.Errorf("Problem getting resources for user %s / %v: %s", user.Name, user.ID, err)
}
for rolesrows.Next() {
grole := ScopeRole{}
if err = rolesrows.Scan(
&grole.ID,
&grole.Name,
&grole.Description); err != nil {
rolesrows.Close()
break
}
gres.ScopeRoles = append(gres.ScopeRoles, grole)
}
if err = rolesrows.Err(); err != nil {
return retval, fmt.Errorf("Problem scanning roles for user %s / %v & resource %s / %v: %s", user.Name, user.ID, gres.Name, gres.ID, err)
}
retval.ScopeResources = append(retval.ScopeResources, gres)
}
if err = rows.Err(); err != nil {
return retval, fmt.Errorf("Problem scanning resources for user %s / %v: %s", user.Name, user.ID, err)
}
return retval, nil
}