authenticate: apply branding to sign out pages (#5044)

Add support for the Enterprise branding options to the sign_out and
signed_out page handlers.
This commit is contained in:
Kenneth Jenkins 2024-04-01 11:32:29 -07:00 committed by GitHub
parent 40655e491a
commit e8edb465f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 67 additions and 6 deletions

View file

@ -89,7 +89,7 @@ func (a *Authenticate) mountDashboard(r *mux.Router) {
// routes that don't need a session:
sr.Path("/sign_out").Handler(httputil.HandlerFunc(a.SignOut))
sr.Path("/signed_out").Handler(handlers.SignedOut(handlers.SignedOutData{})).Methods(http.MethodGet)
sr.Path("/signed_out").Handler(httputil.HandlerFunc(a.signedOut)).Methods(http.MethodGet)
// routes that need a session:
sr = sr.NewRoute().Subrouter()
@ -186,7 +186,8 @@ func (a *Authenticate) SignOut(w http.ResponseWriter, r *http.Request) error {
}
handlers.SignOutConfirm(handlers.SignOutConfirmData{
URL: urlutil.SignOutURL(r, authenticateURL, a.state.Load().sharedKey),
URL: urlutil.SignOutURL(r, authenticateURL, a.state.Load().sharedKey),
BrandingOptions: a.options.Load().BrandingOptions,
}).ServeHTTP(w, r)
return nil
}
@ -240,6 +241,13 @@ func (a *Authenticate) signOutRedirect(w http.ResponseWriter, r *http.Request) e
return nil
}
func (a *Authenticate) signedOut(w http.ResponseWriter, r *http.Request) error {
handlers.SignedOut(handlers.SignedOutData{
BrandingOptions: a.options.Load().BrandingOptions,
}).ServeHTTP(w, r)
return nil
}
// reauthenticateOrFail starts the authenticate process by redirecting the
// user to their respective identity provider. This function also builds the
// 'state' parameter which is encrypted and includes authenticating data

View file

@ -16,9 +16,11 @@ import (
"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/chacha20poly1305"
"golang.org/x/oauth2"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/internal/atomicutil"
@ -33,6 +35,7 @@ import (
"github.com/pomerium/pomerium/internal/testutil"
"github.com/pomerium/pomerium/internal/urlutil"
"github.com/pomerium/pomerium/pkg/cryptutil"
configproto "github.com/pomerium/pomerium/pkg/grpc/config"
"github.com/pomerium/pomerium/pkg/grpc/databroker"
)
@ -619,6 +622,49 @@ func TestAuthenticate_CORS(t *testing.T) {
})
}
func TestSignOutBranding(t *testing.T) {
t.Parallel()
auth := testAuthenticate()
auth.state.Load().flow.(*stubFlow).verifySignatureErr = errors.New("unsigned URL")
auth.options.Store(&config.Options{
BrandingOptions: &configproto.Settings{
PrimaryColor: proto.String("red"),
SecondaryColor: proto.String("orange"),
},
})
t.Run("sign_out", func(t *testing.T) {
t.Parallel()
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/.pomerium/sign_out", nil)
err := auth.SignOut(w, r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, w.Code)
b, err := io.ReadAll(w.Body)
require.NoError(t, err)
assert.Contains(t, string(b), `"primaryColor":"red","secondaryColor":"orange"`)
})
t.Run("signed_out", func(t *testing.T) {
t.Parallel()
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/.pomerium/signed_out", nil)
err := auth.signedOut(w, r)
require.NoError(t, err)
require.Equal(t, http.StatusOK, w.Code)
b, err := io.ReadAll(w.Body)
require.NoError(t, err)
assert.Contains(t, string(b), `"primaryColor":"red","secondaryColor":"orange"`)
})
}
type mockDataBrokerServiceClient struct {
databroker.DataBrokerServiceClient

View file

@ -8,11 +8,15 @@ import (
)
// SignedOutData is the data for the SignedOut page.
type SignedOutData struct{}
type SignedOutData struct {
BrandingOptions httputil.BrandingOptions
}
// ToJSON converts the data into a JSON map.
func (data SignedOutData) ToJSON() map[string]interface{} {
return map[string]interface{}{}
m := map[string]interface{}{}
httputil.AddBrandingOptionsToMap(m, data.BrandingOptions)
return m
}
// SignedOut returns a handler that renders the signed out page.

View file

@ -9,14 +9,17 @@ import (
// SignOutConfirmData is the data for the SignOutConfirm page.
type SignOutConfirmData struct {
URL string
URL string
BrandingOptions httputil.BrandingOptions
}
// ToJSON converts the data into a JSON map.
func (data SignOutConfirmData) ToJSON() map[string]interface{} {
return map[string]interface{}{
m := map[string]interface{}{
"url": data.URL,
}
httputil.AddBrandingOptionsToMap(m, data.BrandingOptions)
return m
}
// SignOutConfirm returns a handler that renders the sign out confirm page.