Skip to content

Commit

Permalink
Manipulate cookies via CookieManager
Browse files Browse the repository at this point in the history
  • Loading branch information
carmenlau committed Jul 26, 2021
2 parents a94681f + fcae3ca commit aa7b7e2
Show file tree
Hide file tree
Showing 29 changed files with 999 additions and 940 deletions.
20 changes: 10 additions & 10 deletions pkg/admin/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pkg/auth/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ var DependencySet = wire.NewSet(
wire.Bind(new(interaction.NonceService), new(*nonce.Service)),

wire.Bind(new(webapp.GraphService), new(*interaction.Service)),
wire.Bind(new(webapp.CookieFactory), new(*httputil.CookieFactory)),
wire.Bind(new(webapp.CookieManager), new(*httputil.CookieManager)),
wire.Bind(new(handlerwebapp.CookieManager), new(*httputil.CookieManager)),

wire.NewSet(
wire.Struct(new(MainOriginProvider), "*"),
Expand Down
13 changes: 13 additions & 0 deletions pkg/auth/handler/webapp/cookie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package webapp

import (
"net/http"

"github.com/authgear/authgear-server/pkg/util/httputil"
)

type CookieManager interface {
GetCookie(r *http.Request, def *httputil.CookieDef) (*http.Cookie, error)
ValueCookie(def *httputil.CookieDef, value string) *http.Cookie
ClearCookie(def *httputil.CookieDef) *http.Cookie
}
3 changes: 2 additions & 1 deletion pkg/auth/handler/webapp/select_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type SelectAccountHandler struct {
SignedUpCookie webapp.SignedUpCookieDef
Users SelectAccountUserService
Identities SelectAccountIdentityService
Cookies CookieManager
}

func (h *SelectAccountHandler) GetData(r *http.Request, rw http.ResponseWriter, userID string) (map[string]interface{}, error) {
Expand Down Expand Up @@ -92,7 +93,7 @@ func (h *SelectAccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
return nil
}
gotoSignupOrLogin := func() {
signedUpCookie, err := r.Cookie(h.SignedUpCookie.Def.Name)
signedUpCookie, err := h.Cookies.GetCookie(r, h.SignedUpCookie.Def)
signedUp := (err == nil && signedUpCookie.Value == "true")
path := GetAuthenticationEndpoint(signedUp, h.AuthenticationConfig.PublicSignupDisabled)
http.Redirect(w, r, path, http.StatusFound)
Expand Down
8 changes: 4 additions & 4 deletions pkg/auth/webapp/client_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ClientIDMiddleware struct {
States SessionMiddlewareStore
SessionCookieDef SessionCookieDef
ClientIDCookieDef ClientIDCookieDef
CookieFactory CookieFactory
Cookies CookieManager
}

func (m *ClientIDMiddleware) Handle(next http.Handler) http.Handler {
Expand All @@ -21,7 +21,7 @@ func (m *ClientIDMiddleware) Handle(next http.Handler) http.Handler {
// Persist client_id into cookie.
// So that client_id no longer need to be present on the query.
if ok {
cookie := m.CookieFactory.ValueCookie(m.ClientIDCookieDef.Def, clientID)
cookie := m.Cookies.ValueCookie(m.ClientIDCookieDef.Def, clientID)
httputil.UpdateCookie(w, cookie)
}

Expand All @@ -47,15 +47,15 @@ func (m *ClientIDMiddleware) ReadClientID(r *http.Request) (clientID string, ok
return
}

if cookie, err := r.Cookie(m.SessionCookieDef.Def.Name); err == nil {
if cookie, err := m.Cookies.GetCookie(r, m.SessionCookieDef.Def); err == nil {
if s, err := m.States.Get(cookie.Value); err == nil && s.ClientID != "" {
clientID = s.ClientID
ok = true
return
}
}

if cookie, err := r.Cookie(m.ClientIDCookieDef.Def.Name); err == nil {
if cookie, err := m.Cookies.GetCookie(r, m.ClientIDCookieDef.Def); err == nil {
clientID = cookie.Value
ok = true
return
Expand Down
52 changes: 17 additions & 35 deletions pkg/auth/webapp/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"net/http"

"github.com/authgear/authgear-server/pkg/api/apierrors"
"github.com/authgear/authgear-server/pkg/lib/config"
"github.com/authgear/authgear-server/pkg/util/duration"
"github.com/authgear/authgear-server/pkg/util/httputil"
)

type CookieFactory interface {
type CookieManager interface {
GetCookie(r *http.Request, def *httputil.CookieDef) (*http.Cookie, error)
ValueCookie(def *httputil.CookieDef, value string) *http.Cookie
ClearCookie(def *httputil.CookieDef) *http.Cookie
}
Expand All @@ -20,86 +20,68 @@ type SessionCookieDef struct {
Def *httputil.CookieDef
}

func NewSessionCookieDef(httpCfg *config.HTTPConfig) SessionCookieDef {
func NewSessionCookieDef() SessionCookieDef {
def := &httputil.CookieDef{
Name: httpCfg.CookiePrefix + "web_session",
NameSuffix: "web_session",
Path: "/",
AllowScriptAccess: false,
SameSite: http.SameSiteNoneMode, // For resumption after redirecting from OAuth providers
MaxAge: nil, // Use HTTP session cookie; expires when browser closes
}

if httpCfg.CookieDomain != nil {
def.Domain = *httpCfg.CookieDomain
}

return SessionCookieDef{Def: def}
}

type ErrorCookieDef struct {
Def *httputil.CookieDef
}

func NewErrorCookieDef(httpCfg *config.HTTPConfig) ErrorCookieDef {
func NewErrorCookieDef() ErrorCookieDef {
def := &httputil.CookieDef{
Name: httpCfg.CookiePrefix + "web_err",
NameSuffix: "web_err",
Path: "/",
AllowScriptAccess: false,
SameSite: http.SameSiteLaxMode,
MaxAge: nil, // Use HTTP session cookie; expires when browser closes
}

if httpCfg.CookieDomain != nil {
def.Domain = *httpCfg.CookieDomain
}

return ErrorCookieDef{Def: def}
}

type SignedUpCookieDef struct {
Def *httputil.CookieDef
}

func NewSignedUpCookieDef(httpCfg *config.HTTPConfig) SignedUpCookieDef {
func NewSignedUpCookieDef() SignedUpCookieDef {
long := int(duration.Long.Seconds())
def := &httputil.CookieDef{
Name: httpCfg.CookiePrefix + "signed_up",
NameSuffix: "signed_up",
Path: "/",
AllowScriptAccess: false,
SameSite: http.SameSiteLaxMode,
MaxAge: &long,
}

if httpCfg.CookieDomain != nil {
def.Domain = *httpCfg.CookieDomain
}

return SignedUpCookieDef{Def: def}
}

type ErrorCookie struct {
Cookie ErrorCookieDef
CookieFactory CookieFactory
Cookie ErrorCookieDef
Cookies CookieManager
}

type ClientIDCookieDef struct {
Def *httputil.CookieDef
}

func NewClientIDCookieDef(httpCfg *config.HTTPConfig) ClientIDCookieDef {
func NewClientIDCookieDef() ClientIDCookieDef {
def := &httputil.CookieDef{
Name: "client_id",
Path: "/",
SameSite: http.SameSiteNoneMode,
}
if httpCfg.CookieDomain != nil {
def.Domain = *httpCfg.CookieDomain
NameSuffix: "client_id",
Path: "/",
SameSite: http.SameSiteNoneMode,
}
return ClientIDCookieDef{Def: def}
}

func (c *ErrorCookie) GetError(r *http.Request) (*apierrors.APIError, bool) {
cookie, err := r.Cookie(c.Cookie.Def.Name)
cookie, err := c.Cookies.GetCookie(r, c.Cookie.Def)
if err != nil || cookie.Value == "" {
return nil, false
}
Expand All @@ -117,7 +99,7 @@ func (c *ErrorCookie) GetError(r *http.Request) (*apierrors.APIError, bool) {
}

func (c *ErrorCookie) ResetError() *http.Cookie {
cookie := c.CookieFactory.ClearCookie(c.Cookie.Def)
cookie := c.Cookies.ClearCookie(c.Cookie.Def)
return cookie
}

Expand All @@ -128,6 +110,6 @@ func (c *ErrorCookie) SetError(value *apierrors.APIError) (*http.Cookie, error)
}

cookieValue := base64.RawURLEncoding.EncodeToString(data)
cookie := c.CookieFactory.ValueCookie(c.Cookie.Def, cookieValue)
cookie := c.Cookies.ValueCookie(c.Cookie.Def, cookieValue)
return cookie, nil
}
8 changes: 2 additions & 6 deletions pkg/auth/webapp/login_hint.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,14 @@ type LoginHintPageService interface {
PostWithIntent(session *Session, intent interaction.Intent, inputFn func() (interface{}, error)) (*Result, error)
}

type LoginHintCookieFactory interface {
ValueCookie(def *httputil.CookieDef, value string) *http.Cookie
}

type LoginHintHandler struct {
Config *config.OAuthConfig
Anonymous AnonymousIdentityProvider
OfflineGrants oauth.OfflineGrantStore
AppSessionTokens oauth.AppSessionTokenStore
AppSessions oauth.AppSessionStore
Clock clock.Clock
CookieFactory CookieFactory
Cookies CookieManager
SessionCookie session.CookieDef
Pages LoginHintPageService
}
Expand Down Expand Up @@ -104,7 +100,7 @@ func (r *LoginHintHandler) HandleLoginHint(options HandleLoginHintOptions) (http
return nil, nil
}

cookie := r.CookieFactory.ValueCookie(r.SessionCookie.Def, token)
cookie := r.Cookies.ValueCookie(r.SessionCookie.Def, token)
return &Result{
Cookies: []*http.Cookie{cookie},
RedirectURI: options.OriginalRedirectURI,
Expand Down
12 changes: 6 additions & 6 deletions pkg/auth/webapp/service2.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type Service2 struct {
SignedUpCookie SignedUpCookieDef
MFADeviceTokenCookie mfa.CookieDef
ErrorCookie *ErrorCookie
CookieFactory CookieFactory
Cookies CookieManager

Graph GraphService
}
Expand All @@ -59,7 +59,7 @@ func (s *Service2) CreateSession(session *Session, redirectURI string) (*Result,
}
result := &Result{
RedirectURI: redirectURI,
Cookies: []*http.Cookie{s.CookieFactory.ValueCookie(s.SessionCookie.Def, session.ID)},
Cookies: []*http.Cookie{s.Cookies.ValueCookie(s.SessionCookie.Def, session.ID)},
}
return result, nil
}
Expand Down Expand Up @@ -164,7 +164,7 @@ func (s *Service2) doPost(
switch kind {
case SessionStepAuthenticate:
authDeviceToken := ""
if deviceTokenCookie, err := s.Request.Cookie(s.MFADeviceTokenCookie.Def.Name); err == nil {
if deviceTokenCookie, err := s.Cookies.GetCookie(s.Request, s.MFADeviceTokenCookie.Def); err == nil {
for _, edge := range edges {
if _, ok := edge.(*nodes.EdgeUseDeviceToken); ok {
authDeviceToken = deviceTokenCookie.Value
Expand Down Expand Up @@ -354,7 +354,7 @@ func (s *Service2) afterPost(
// Marked signed up in cookie after authorization.
// When user visit auth ui root "/", redirect user to "/login" if
// cookie exists
result.Cookies = append(result.Cookies, s.CookieFactory.ValueCookie(s.SignedUpCookie.Def, "true"))
result.Cookies = append(result.Cookies, s.Cookies.ValueCookie(s.SignedUpCookie.Def, "true"))
default:
// Use the default navigation action for any other intents.
// That is, "advance" will be used.
Expand Down Expand Up @@ -393,13 +393,13 @@ func (s *Service2) afterPost(
if err != nil {
return err
}
result.Cookies = append(result.Cookies, s.CookieFactory.ClearCookie(s.SessionCookie.Def))
result.Cookies = append(result.Cookies, s.Cookies.ClearCookie(s.SessionCookie.Def))
} else if isNewGraph {
err := s.Sessions.Create(session)
if err != nil {
return err
}
result.Cookies = append(result.Cookies, s.CookieFactory.ValueCookie(s.SessionCookie.Def, session.ID))
result.Cookies = append(result.Cookies, s.Cookies.ValueCookie(s.SessionCookie.Def, session.ID))
} else if interactionErr == nil {
err := s.Sessions.Update(session)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions pkg/auth/webapp/session_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ type SessionMiddlewareStore interface {
}

type SessionMiddleware struct {
States SessionMiddlewareStore
Cookie SessionCookieDef
CookieFactory CookieFactory
States SessionMiddlewareStore
CookieDef SessionCookieDef
Cookies CookieManager
}

func (m *SessionMiddleware) Handle(next http.Handler) http.Handler {
Expand All @@ -26,7 +26,7 @@ func (m *SessionMiddleware) Handle(next http.Handler) http.Handler {
return
} else if errors.Is(err, ErrInvalidSession) {
// Clear the session before continuing
cookie := m.CookieFactory.ClearCookie(m.Cookie.Def)
cookie := m.Cookies.ClearCookie(m.CookieDef.Def)
httputil.UpdateCookie(w, cookie)
next.ServeHTTP(w, r)
return
Expand All @@ -41,7 +41,7 @@ func (m *SessionMiddleware) Handle(next http.Handler) http.Handler {
}

func (m *SessionMiddleware) loadSession(r *http.Request) (*Session, error) {
cookie, err := r.Cookie(m.Cookie.Def.Name)
cookie, err := m.Cookies.GetCookie(r, m.CookieDef.Def)
if err != nil {
return nil, ErrSessionNotFound
}
Expand Down
Loading

0 comments on commit aa7b7e2

Please sign in to comment.