go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/appengine/gaeauth/server/default.go (about) 1 // Copyright 2015 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package server 16 17 import ( 18 "context" 19 20 "google.golang.org/appengine" 21 22 "go.chromium.org/luci/server/auth" 23 "go.chromium.org/luci/server/auth/deprecated" 24 "go.chromium.org/luci/server/encryptedcookies" 25 "go.chromium.org/luci/server/encryptedcookies/session/datastore" 26 "go.chromium.org/luci/server/router" 27 "go.chromium.org/luci/server/warmup" 28 29 "go.chromium.org/luci/appengine/gaeauth/server/internal/authdbimpl" 30 "go.chromium.org/luci/appengine/gaemiddleware" 31 ) 32 33 var handlersInstalled = false 34 35 // CookieAuth is default cookie-based auth method to use on GAE. 36 // 37 // By default on the dev server it is based on dev server cookies (implemented 38 // by UsersAPIAuthMethod), in prod it is based on OpenID (implemented by 39 // *deprecated.CookieAuthMethod). 40 // 41 // Works only if appropriate handlers have been installed into the router. See 42 // InstallHandlers. 43 // 44 // It is allowed to assign to CookieAuth (e.g. to install a tweaked auth method) 45 // before InstallHandlers is called. In particular, use SwitchToEncryptedCookies 46 // to update to a better (but incompatible) method. 47 // 48 // Deprecated: this method depends on Users API not available outside of the GAE 49 // first-gen runtime and uses deprecated CookieAuthMethod. Use 50 // go.chromium.org/luci/server/encryptedcookies instead. To facilitate the 51 // migration you can switch to the encrypted cookies while still running on 52 // the GAE first-gen runtime by calling SwitchToEncryptedCookies() early during 53 // the server initialization. 54 var CookieAuth auth.Method 55 56 // DisableCookieAuth stops all cookie-based authentication. 57 // 58 // Must be called before InstallHandlers. 59 func DisableCookieAuth() { 60 if handlersInstalled { 61 panic("DisableCookieAuth must be called before InstallHandlers") 62 } 63 CookieAuth = nil 64 } 65 66 // SwitchToEncryptedCookies opts-in CookieAuth to use a better implementation. 67 // 68 // The "better implementation" is not backward compatible with the previous one, 69 // i.e. all existing user sessions are ignored. Calling this function is an 70 // acknowledgment that it is OK to relogin all users when making the switch. 71 // 72 // Must be called before InstallHandlers. 73 func SwitchToEncryptedCookies() { 74 if handlersInstalled { 75 panic("SwitchToEncryptedCookies must be called before InstallHandlers") 76 } 77 if method, ok := CookieAuth.(*deprecated.CookieAuthMethod); ok { 78 // Upgrade! Reuse OpenID config in the settings. 79 CookieAuth = &encryptedcookies.AuthMethod{ 80 OpenIDConfig: func(ctx context.Context) (*encryptedcookies.OpenIDConfig, error) { 81 s, err := deprecated.FetchOpenIDSettings(ctx) 82 if err != nil { 83 return nil, err 84 } 85 return &encryptedcookies.OpenIDConfig{ 86 DiscoveryURL: s.DiscoveryURL, 87 ClientID: s.ClientID, 88 ClientSecret: s.ClientSecret, 89 RedirectURI: s.RedirectURI, 90 }, nil 91 }, 92 AEADProvider: gaemiddleware.AEADProvider, 93 Sessions: &datastore.Store{}, 94 Insecure: method.Insecure, 95 IncompatibleCookies: method.IncompatibleCookies, 96 } 97 } 98 } 99 100 // InstallHandlers installs HTTP handlers for various default routes related 101 // to authentication system. 102 // 103 // Must be installed in server HTTP router for authentication to work. 104 func InstallHandlers(r *router.Router, base router.MiddlewareChain) { 105 if m, ok := CookieAuth.(auth.HasHandlers); ok { 106 m.InstallHandlers(r, base) 107 } 108 auth.InstallHandlers(r, base) 109 authdbimpl.InstallHandlers(r, base) 110 handlersInstalled = true 111 } 112 113 func init() { 114 warmup.Register("appengine/gaeauth/server", func(ctx context.Context) error { 115 if m, ok := CookieAuth.(auth.Warmable); ok { 116 return m.Warmup(ctx) 117 } 118 return nil 119 }) 120 121 // Flip to true to enable OpenID login on devserver for debugging. Requires 122 // a configuration (see /admin/portal/openid_auth page). 123 const useOIDOnDevServer = false 124 125 if appengine.IsDevAppServer() && !useOIDOnDevServer { 126 CookieAuth = UsersAPIAuthMethod{} 127 } else { 128 CookieAuth = &deprecated.CookieAuthMethod{ 129 SessionStore: &SessionStore{Prefix: "openid"}, 130 IncompatibleCookies: []string{"SACSID", "dev_appserver_login"}, 131 Insecure: appengine.IsDevAppServer(), // for http:// cookie 132 } 133 } 134 }