/
auth.go
98 lines (87 loc) · 2.52 KB
/
auth.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
package gocouch
import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
)
// Auth is a common interface that provides
// methods
type Auth interface {
// AddAuthHeaders add authorisation headers
AddAuthHeaders(*http.Request)
}
// BasicAuth provides simple user:password authentication
type BasicAuth struct {
Username, Password string
}
// AddAuthHeaders used to add authentication headers to the request
func (ba BasicAuth) AddAuthHeaders(req *http.Request) {
authString := []byte(ba.Username + ":" + ba.Password)
header := "Basic " + base64.StdEncoding.EncodeToString(authString)
req.Header.Add("Authorization", header)
}
// Session stores authentication cookie for current user at the CouchDB instance
type Session struct {
cookie *http.Cookie
srv *Server
}
// AddAuthHeaders add cookie to request
func (s Session) AddAuthHeaders(req *http.Request) {
req.AddCookie(s.cookie)
}
// UserRecord is userd to create new user in couchdb instance
type UserRecord struct {
Login string `json:"name"`
Type string `json:"type"`
Roles []string `json:"roles"`
Password string `json:"password"`
}
// CreateUser inserts user record to couchdb _users database
func (srv *Server) CreateUser(user *UserRecord) error {
db, err := srv.MustGetDatabase("_users", srv.auth)
if err != nil {
return err
}
_, err = db.Put(fmt.Sprintf("org.couchdb.user:%s", user.Login), user)
return err
}
// NewSession authenticates user and returns Session struct containing current
// session token
func (srv *Server) NewSession(user, pass string) (*Session, error) {
request := map[string]string{"name": user, "password": pass}
headers := map[string]string{"Content-Type": appJSON}
payload, err := json.Marshal(request)
if err != nil {
return nil, err
}
resp, err := srv.conn.request("POST", "/_session", headers, bytes.NewReader(payload), srv.auth, 0)
if err != nil {
return nil, err
}
s := Session{srv: srv}
for _, cookie := range resp.Cookies() {
if cookie.Name == "AuthSession" {
s.cookie = cookie
}
}
return &s, nil
}
// Info returns information about current session info
func (s *Session) Info() (map[string]interface{}, error) {
resp, err := s.srv.conn.request("GET", "/_session", nil, nil, s, 0)
if err != nil {
return nil, err
}
var result map[string]interface{}
if err := parseBody(resp, &result); err != nil {
return nil, err
}
return result, nil
}
// Close deletes current session
func (s *Session) Close() error {
_, err := s.srv.conn.request("DELETE", "/_session", nil, nil, s, 0)
return err
}