github.com/volatiletech/authboss@v2.4.1+incompatible/context.go (about) 1 package authboss 2 3 import ( 4 "context" 5 "net/http" 6 ) 7 8 type contextKey string 9 10 // CTX Keys for authboss 11 const ( 12 CTXKeyPID contextKey = "pid" 13 CTXKeyUser contextKey = "user" 14 15 CTXKeySessionState contextKey = "session" 16 CTXKeyCookieState contextKey = "cookie" 17 18 // CTXKeyData is a context key for the accumulating 19 // map[string]interface{} (authboss.HTMLData) to pass to the 20 // renderer 21 CTXKeyData contextKey = "data" 22 23 // CTXKeyValues is to pass the data submitted from API request or form 24 // along in the context in case modules need it. The only module that needs 25 // user information currently is remember so only auth/oauth2 are currently 26 // going to use this. 27 CTXKeyValues contextKey = "values" 28 ) 29 30 func (c contextKey) String() string { 31 return "authboss ctx key " + string(c) 32 } 33 34 // CurrentUserID retrieves the current user from the session. 35 // TODO(aarondl): This method never returns an error, one day we'll change 36 // the function signature. 37 func (a *Authboss) CurrentUserID(r *http.Request) (string, error) { 38 if pid := r.Context().Value(CTXKeyPID); pid != nil { 39 return pid.(string), nil 40 } 41 42 pid, _ := GetSession(r, SessionKey) 43 return pid, nil 44 } 45 46 // CurrentUserIDP retrieves the current user but panics if it's not available for 47 // any reason. 48 func (a *Authboss) CurrentUserIDP(r *http.Request) string { 49 i, err := a.CurrentUserID(r) 50 if err != nil { 51 panic(err) 52 } else if len(i) == 0 { 53 panic(ErrUserNotFound) 54 } 55 56 return i 57 } 58 59 // CurrentUser retrieves the current user from the session and the database. 60 // Before the user is loaded from the database the context key is checked. 61 // If the session doesn't have the user ID ErrUserNotFound will be returned. 62 func (a *Authboss) CurrentUser(r *http.Request) (User, error) { 63 if user := r.Context().Value(CTXKeyUser); user != nil { 64 return user.(User), nil 65 } 66 67 pid, err := a.CurrentUserID(r) 68 if err != nil { 69 return nil, err 70 } else if len(pid) == 0 { 71 return nil, ErrUserNotFound 72 } 73 74 return a.currentUser(r.Context(), pid) 75 } 76 77 // CurrentUserP retrieves the current user but panics if it's not available for 78 // any reason. 79 func (a *Authboss) CurrentUserP(r *http.Request) User { 80 i, err := a.CurrentUser(r) 81 if err != nil { 82 panic(err) 83 } else if i == nil { 84 panic(ErrUserNotFound) 85 } 86 return i 87 } 88 89 func (a *Authboss) currentUser(ctx context.Context, pid string) (User, error) { 90 return a.Storage.Server.Load(ctx, pid) 91 } 92 93 // LoadCurrentUserID takes a pointer to a pointer to the request in order to 94 // change the current method's request pointer itself to the new request that 95 // contains the new context that has the pid in it. 96 func (a *Authboss) LoadCurrentUserID(r **http.Request) (string, error) { 97 pid, err := a.CurrentUserID(*r) 98 if err != nil { 99 return "", err 100 } 101 102 if len(pid) == 0 { 103 return "", nil 104 } 105 106 ctx := context.WithValue((**r).Context(), CTXKeyPID, pid) 107 *r = (**r).WithContext(ctx) 108 109 return pid, nil 110 } 111 112 // LoadCurrentUserIDP loads the current user id and panics if it's not found 113 func (a *Authboss) LoadCurrentUserIDP(r **http.Request) string { 114 pid, err := a.LoadCurrentUserID(r) 115 if err != nil { 116 panic(err) 117 } else if len(pid) == 0 { 118 panic(ErrUserNotFound) 119 } 120 121 return pid 122 } 123 124 // LoadCurrentUser takes a pointer to a pointer to the request in order to 125 // change the current method's request pointer itself to the new request that 126 // contains the new context that has the user in it. Calls LoadCurrentUserID 127 // so the primary id is also put in the context. 128 func (a *Authboss) LoadCurrentUser(r **http.Request) (User, error) { 129 if user := (*r).Context().Value(CTXKeyUser); user != nil { 130 return user.(User), nil 131 } 132 133 pid, err := a.LoadCurrentUserID(r) 134 if err != nil { 135 return nil, err 136 } else if len(pid) == 0 { 137 return nil, ErrUserNotFound 138 } 139 140 ctx := (**r).Context() 141 user, err := a.currentUser(ctx, pid) 142 if err != nil { 143 return nil, err 144 } 145 146 ctx = context.WithValue(ctx, CTXKeyUser, user) 147 *r = (**r).WithContext(ctx) 148 return user, nil 149 } 150 151 // LoadCurrentUserP does the same as LoadCurrentUser but panics if 152 // the current user is not found. 153 func (a *Authboss) LoadCurrentUserP(r **http.Request) User { 154 user, err := a.LoadCurrentUser(r) 155 if err != nil { 156 panic(err) 157 } else if user == nil { 158 panic(ErrUserNotFound) 159 } 160 161 return user 162 }