forked from volatiletech/authboss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
162 lines (134 loc) · 4.14 KB
/
context.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package authboss
import (
"context"
"net/http"
)
type contextKey string
// CTX Keys for authboss
const (
CTXKeyPID contextKey = "pid"
CTXKeyUser contextKey = "user"
CTXKeySessionState contextKey = "session"
CTXKeyCookieState contextKey = "cookie"
// CTXKeyData is a context key for the accumulating
// map[string]interface{} (authboss.HTMLData) to pass to the
// renderer
CTXKeyData contextKey = "data"
// CTXKeyValues is to pass the data submitted from API request or form
// along in the context in case modules need it. The only module that needs
// user information currently is remember so only auth/oauth2 are currently
// going to use this.
CTXKeyValues contextKey = "values"
)
func (c contextKey) String() string {
return "authboss ctx key " + string(c)
}
// CurrentUserID retrieves the current user from the session.
// TODO(aarondl): This method never returns an error, one day we'll change
// the function signature.
func (a *Authboss) CurrentUserID(r *http.Request) (string, error) {
if pid := r.Context().Value(CTXKeyPID); pid != nil {
return pid.(string), nil
}
pid, _ := GetSession(r, SessionKey)
return pid, nil
}
// CurrentUserIDP retrieves the current user but panics if it's not available for
// any reason.
func (a *Authboss) CurrentUserIDP(r *http.Request) string {
i, err := a.CurrentUserID(r)
if err != nil {
panic(err)
} else if len(i) == 0 {
panic(ErrUserNotFound)
}
return i
}
// CurrentUser retrieves the current user from the session and the database.
// Before the user is loaded from the database the context key is checked.
// If the session doesn't have the user ID ErrUserNotFound will be returned.
func (a *Authboss) CurrentUser(r *http.Request) (User, error) {
if user := r.Context().Value(CTXKeyUser); user != nil {
return user.(User), nil
}
pid, err := a.CurrentUserID(r)
if err != nil {
return nil, err
} else if len(pid) == 0 {
return nil, ErrUserNotFound
}
return a.currentUser(r.Context(), pid)
}
// CurrentUserP retrieves the current user but panics if it's not available for
// any reason.
func (a *Authboss) CurrentUserP(r *http.Request) User {
i, err := a.CurrentUser(r)
if err != nil {
panic(err)
} else if i == nil {
panic(ErrUserNotFound)
}
return i
}
func (a *Authboss) currentUser(ctx context.Context, pid string) (User, error) {
return a.Storage.Server.Load(ctx, pid)
}
// LoadCurrentUserID takes a pointer to a pointer to the request in order to
// change the current method's request pointer itself to the new request that
// contains the new context that has the pid in it.
func (a *Authboss) LoadCurrentUserID(r **http.Request) (string, error) {
pid, err := a.CurrentUserID(*r)
if err != nil {
return "", err
}
if len(pid) == 0 {
return "", nil
}
ctx := context.WithValue((**r).Context(), CTXKeyPID, pid)
*r = (**r).WithContext(ctx)
return pid, nil
}
// LoadCurrentUserIDP loads the current user id and panics if it's not found
func (a *Authboss) LoadCurrentUserIDP(r **http.Request) string {
pid, err := a.LoadCurrentUserID(r)
if err != nil {
panic(err)
} else if len(pid) == 0 {
panic(ErrUserNotFound)
}
return pid
}
// LoadCurrentUser takes a pointer to a pointer to the request in order to
// change the current method's request pointer itself to the new request that
// contains the new context that has the user in it. Calls LoadCurrentUserID
// so the primary id is also put in the context.
func (a *Authboss) LoadCurrentUser(r **http.Request) (User, error) {
if user := (*r).Context().Value(CTXKeyUser); user != nil {
return user.(User), nil
}
pid, err := a.LoadCurrentUserID(r)
if err != nil {
return nil, err
} else if len(pid) == 0 {
return nil, ErrUserNotFound
}
ctx := (**r).Context()
user, err := a.currentUser(ctx, pid)
if err != nil {
return nil, err
}
ctx = context.WithValue(ctx, CTXKeyUser, user)
*r = (**r).WithContext(ctx)
return user, nil
}
// LoadCurrentUserP does the same as LoadCurrentUser but panics if
// the current user is not found.
func (a *Authboss) LoadCurrentUserP(r **http.Request) User {
user, err := a.LoadCurrentUser(r)
if err != nil {
panic(err)
} else if user == nil {
panic(ErrUserNotFound)
}
return user
}