-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuser.go
136 lines (106 loc) · 3.5 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package sofa
import (
"encoding/json"
"errors"
"fmt"
)
// UserDocument contains all of the fields used by CouchDB to represent a
// user on the server.
type UserDocument struct {
DocumentMetadata
Name string `json:"name"`
Roles []string `json:"roles"`
TheType string `json:"type"`
// This field is never sent back from CouchDB (for obvious reasons)
Password string `json:"password,omitempty"`
// These fields are generated by CouchDB from the password provided on creation
DerivedKey string `json:"derived_key,omitempty"`
Iterations int `json:"iterations,omitempty"`
PasswordScheme string `json:"password_scheme,omitempty"`
Salt string `json:"salt,omitempty"`
}
// Users gets a list of all users currently active on this CouchDB server
func (con *Connection) Users() ([]UserDocument, error) {
db := con.Database("_users")
table, err := db.AllDocuments()
if err != nil {
return nil, err
}
users := []UserDocument{}
for _, rawUser := range table.RawDocuments() {
user := UserDocument{}
if err := json.Unmarshal(rawUser, &user); err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}
// User gets a particular UserDocument from the server by name. A revision can
// also be specified to retrieve a particular revision of the document (or an
// empty string supplied to fetch the current version).
// This makes the assumption that the user exists in the 'org.couchdb.user' namespace
// but I am unaware of any situation where that is not true. If the user doesn't
// exist in this namespace it should be possible to retrieve them with UserByID.
func (con *Connection) User(name string, rev string) (UserDocument, error) {
id := fmt.Sprintf("org.couchdb.user:%s", name)
return con.UserByID(id, rev)
}
// UserByID gets a CouchDB user by the ID of ther user document rather than their
// name.
func (con *Connection) UserByID(id string, rev string) (UserDocument, error) {
db := con.Database("_users")
user := UserDocument{}
_, err := db.Get(&user, id, rev)
if err != nil {
return user, err
}
return user, nil
}
// CreateUser creates a new document in the _users database.
func (con *Connection) CreateUser(user *UserDocument) (string, error) {
db := con.Database("_users")
id := fmt.Sprintf("org.couchdb.user:%s", user.Name)
// For convenience fill in the ID if it was left blank
if user.DocumentMetadata.ID == "" {
user.DocumentMetadata.ID = id
}
rev, err := db.Put(user)
if err != nil {
return "", err
}
user.DocumentMetadata.Rev = rev
return rev, err
}
// DeleteUser deletes an existing user from the _users database.
func (con *Connection) DeleteUser(user *UserDocument) (string, error) {
db := con.Database("_users")
if user.DocumentMetadata.ID == "" {
return "", errors.New("cannot delete a user with an unknown id")
}
if user.DocumentMetadata.Rev == "" {
return "", errors.New("cannot delete a user with no current rev")
}
rev, err := db.Delete(user)
if err != nil {
return "", err
}
user.DocumentMetadata.Rev = rev
return rev, err
}
// UpdateUser modifies details of a user document.
func (con *Connection) UpdateUser(user *UserDocument) (string, error) {
db := con.Database("_users")
if user.DocumentMetadata.ID == "" {
return "", errors.New("cannot update a user with an unknown id")
}
if user.DocumentMetadata.Rev == "" {
return "", errors.New("cannot update a user with no current rev")
}
rev, err := db.Put(user)
if err != nil {
return "", err
}
user.DocumentMetadata.Rev = rev
return rev, err
}