Skip to content

Commit 71da5c4

Browse files
authored
Add Brandable Dialogs (#19)
1 parent 9388737 commit 71da5c4

File tree

9 files changed

+120
-96
lines changed

9 files changed

+120
-96
lines changed

charts/identity/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: A Helm chart for deploying Unikorn's IdP
44

55
type: application
66

7-
version: v0.1.15
8-
appVersion: v0.1.15
7+
version: v0.1.16
8+
appVersion: v0.1.16
99

1010
icon: https://raw.githubusercontent.com/unikorn-cloud/assets/main/images/logos/dark-on-light/icon.png

charts/identity/templates/deployment.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ spec:
2020
args:
2121
- --namespace={{ .Release.Namespace }}
2222
- --host=https://{{ .Values.host }}
23+
{{- with $branding := .Values.branding }}
24+
{{- if $branding.loginRedirectURL }}
25+
{{ printf "- --login-redirect-url=%s" $branding.loginRedirectURL | nindent 8 }}
26+
{{- end }}
27+
{{- if $branding.errorRedirectURL }}
28+
{{ printf "- --error-redirect-url=%s" $branding.errorRedirectURL | nindent 8 }}
29+
{{- end }}
30+
{{- end }}
2331
{{- with $cors := .Values.cors }}
2432
{{- range $origin := $cors.allowOrigin }}
2533
{{ printf "- --cors-allow-origin=%s" $origin | nindent 8 }}

charts/identity/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ image: ~
2121
# oauth2 issuer etc.
2222
host: identity.acme.org
2323

24+
# Branding options allow you to "white-box" and apply your own spin on the
25+
# login and error pages.
26+
# branding:
27+
# loginRedirectURL: https://my-host/login
28+
# errorRedirectURL: https://my-host/error
29+
2430
# A static list of registered client applications.
2531
# clients:
2632
# - # Must be a valid Kubernetes resource name.

openapi/server.spec.yaml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,7 @@ components:
453453
description: Login request options.
454454
type: object
455455
required:
456-
- provider
457-
- query
456+
- state
458457
properties:
459458
email:
460459
description: The user's email address.
@@ -463,12 +462,9 @@ components:
463462
provider:
464463
description: The explcit provider type.
465464
type: string
466-
enum:
467-
- dynamic
468-
- google
469-
- microsoft
470-
query:
471-
description: The query string supplied to the authorization endpoint.
465+
nullable: true
466+
state:
467+
description: The state string supplied by the authorization endpoint.
472468
type: string
473469
tokenRequestOptions:
474470
description: oauth2 token endpoint.

pkg/generated/schema.go

Lines changed: 55 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/generated/types.go

Lines changed: 3 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/oauth2/federated.go

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636

3737
"github.com/coreos/go-oidc/v3/oidc"
3838
"github.com/go-jose/go-jose/v3/jwt"
39+
"github.com/spf13/pflag"
3940
"golang.org/x/oauth2"
4041

4142
"github.com/unikorn-cloud/core/pkg/server/errors"
@@ -50,6 +51,13 @@ import (
5051
)
5152

5253
type Options struct {
54+
loginRedirectURL string
55+
errorRedirectURL string
56+
}
57+
58+
func (o *Options) AddFlags(f *pflag.FlagSet) {
59+
f.StringVar(&o.loginRedirectURL, "login-redirect-url", "", "External page to handle login requests")
60+
f.StringVar(&o.errorRedirectURL, "error-redirect-url", "", "External page to handle errors")
5361
}
5462

5563
// Authenticator provides Keystone authentication functionality.
@@ -384,14 +392,26 @@ func (a *Authenticator) Authorization(w http.ResponseWriter, r *http.Request) {
384392
}
385393
}
386394

395+
loginQuery := url.Values{}
396+
397+
loginQuery.Set("state", query.Encode())
398+
loginQuery.Set("callback", "https://"+r.Host+"/oauth2/v2/login")
399+
400+
// Redirect to an external login handler, if you have chosen to.
401+
if a.options.loginRedirectURL != "" {
402+
http.Redirect(w, r, fmt.Sprintf("%s?%s", a.options.loginRedirectURL, loginQuery.Encode()), http.StatusFound)
403+
return
404+
}
405+
406+
// Otherwise use the internal version.
387407
tmpl, err := template.New("login").Parse(loginTemplate)
388408
if err != nil {
389409
log.Info("oauth2: failed to parse template", "error", err)
390410
return
391411
}
392412

393413
templateContext := map[string]interface{}{
394-
"query": query.Encode(),
414+
"state": query.Encode(),
395415
}
396416

397417
var buffer bytes.Buffer
@@ -566,27 +586,18 @@ func (a *Authenticator) Login(w http.ResponseWriter, r *http.Request) {
566586
return
567587
}
568588

569-
if !r.Form.Has("email") {
570-
log.Info("email doesn't exist in form")
571-
return
572-
}
573-
574-
if !r.Form.Has("query") {
575-
log.Info("query doesn't exist in form")
589+
if !r.Form.Has("state") {
590+
log.Info("state doesn't exist in form")
576591
return
577592
}
578593

579-
if !r.Form.Has("provider") {
580-
log.Info("provider doesn't exist in form")
581-
}
582-
583-
query, err := url.ParseQuery(r.Form.Get("query"))
594+
query, err := url.ParseQuery(r.Form.Get("state"))
584595
if err != nil {
585596
log.Error(err, "failed to parse query")
586597
return
587598
}
588599

589-
if providerType := r.Form.Get("provider"); providerType != "dynamic" {
600+
if providerType := r.Form.Get("provider"); providerType != "" {
590601
provider, err := a.lookupProviderByType(r.Context(), unikornv1.IdentityProviderType(providerType))
591602
if err != nil {
592603
authorizationError(w, r, query.Get("redirect_uri"), ErrorServerError, err.Error())
@@ -608,6 +619,20 @@ func (a *Authenticator) Login(w http.ResponseWriter, r *http.Request) {
608619
return
609620
}
610621

622+
// Remove the cookie otherwise.
623+
cookie := &http.Cookie{
624+
Name: ProviderCookie,
625+
Value: "undefined",
626+
MaxAge: -1,
627+
}
628+
629+
w.Header().Add("Set-Cookie", cookie.String())
630+
631+
if !r.Form.Has("email") {
632+
log.Info("email doesn't exist in form")
633+
return
634+
}
635+
611636
organization, err := a.lookupOrganization(r.Context(), r.Form.Get("email"))
612637
if err != nil {
613638
authorizationError(w, r, query.Get("redirect_uri"), ErrorServerError, err.Error())

pkg/oauth2/login.tmpl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,8 @@
7171
function submitWithProvider(provider) {
7272
const providerInput = document.getElementById('provider');
7373
providerInput.value = provider;
74-
console.log(providerInput);
7574

7675
const form = document.getElementById('form');
77-
console.log(form);
7876
form.submit();
7977
}
8078
</script>
@@ -87,10 +85,10 @@
8785
<main>
8886
<form id="form" method="post" action="/oauth2/v2/login">
8987
<!-- Use this to hold state across the dialog -->
90-
<input id="query" name="query" type="hidden" value="{{ .query }}" />
88+
<input id="state" name="state" type="hidden" value="{{ .state }}" />
9189

9290
<!-- Use this to cummuncate the provider to use -->
93-
<input id="provider" name="provider" type="hidden" value="dynamic"/>
91+
<input id="provider" name="provider" type="hidden" value=""/>
9492

9593
<section>
9694
<p>Enter your e-mail address to continue if using a domain login</p>

pkg/server/server.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func (s *Server) AddFlags(goflags *flag.FlagSet, flags *pflag.FlagSet) {
7272
s.Options.AddFlags(flags)
7373
s.HandlerOptions.AddFlags(flags)
7474
s.JoseOptions.AddFlags(flags)
75+
s.OAuth2Options.AddFlags(flags)
7576
s.CORSOptions.AddFlags(flags)
7677
}
7778

0 commit comments

Comments
 (0)