From 0b5fd156e856d911339ee7fc1dd99091da970ed0 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Thu, 21 May 2020 12:09:11 -0700 Subject: [PATCH 1/2] Add a third principal on OIDC tokens with the raw local part of the email. For the email first.last@example.com it will create the principals ["firstlast", "first.last", "first.last@example.com"] Fixes #253, #254 --- authority/provisioner/provisioner.go | 15 ++++++++++++++- authority/provisioner/provisioner_test.go | 23 ++++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/authority/provisioner/provisioner.go b/authority/provisioner/provisioner.go index 885e7cf0..4d8671e7 100644 --- a/authority/provisioner/provisioner.go +++ b/authority/provisioner/provisioner.go @@ -336,11 +336,24 @@ type GetIdentityFunc func(ctx context.Context, p Interface, email string) (*Iden func DefaultIdentityFunc(ctx context.Context, p Interface, email string) (*Identity, error) { switch k := p.(type) { case *OIDC: + // OIDC principals would be: + // 1. Sanitized local. + // 2. Raw local (if different). + // 3. Email address. name := SanitizeSSHUserPrincipal(email) if !sshUserRegex.MatchString(name) { return nil, errors.Errorf("invalid principal '%s' from email '%s'", name, email) } - return &Identity{Usernames: []string{name, email}}, nil + usernames := []string{name} + if i := strings.LastIndex(email, "@"); i >= 0 { + if local := email[:i]; !strings.EqualFold(local, name) { + usernames = append(usernames, local) + } + } + usernames = append(usernames, email) + return &Identity{ + Usernames: usernames, + }, nil default: return nil, errors.Errorf("provisioner type '%T' not supported by identity function", k) } diff --git a/authority/provisioner/provisioner_test.go b/authority/provisioner/provisioner_test.go index 238e21a3..39ce2e2e 100644 --- a/authority/provisioner/provisioner_test.go +++ b/authority/provisioner/provisioner_test.go @@ -85,7 +85,28 @@ func TestDefaultIdentityFunc(t *testing.T) { return test{ p: &OIDC{}, email: "max.furman@smallstep.com", - identity: &Identity{Usernames: []string{"maxfurman", "max.furman@smallstep.com"}}, + identity: &Identity{Usernames: []string{"maxfurman", "max.furman", "max.furman@smallstep.com"}}, + } + }, + "ok letter case": func(t *testing.T) test { + return test{ + p: &OIDC{}, + email: "Max.Furman@smallstep.com", + identity: &Identity{Usernames: []string{"maxfurman", "Max.Furman", "Max.Furman@smallstep.com"}}, + } + }, + "ok simple": func(t *testing.T) test { + return test{ + p: &OIDC{}, + email: "john@smallstep.com", + identity: &Identity{Usernames: []string{"john", "john@smallstep.com"}}, + } + }, + "ok simple letter case": func(t *testing.T) test { + return test{ + p: &OIDC{}, + email: "John@smallstep.com", + identity: &Identity{Usernames: []string{"john", "John@smallstep.com"}}, } }, } From 3246a3e81f623dab008718d8d5ae78c9d7c7d220 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Tue, 26 May 2020 10:22:15 -0700 Subject: [PATCH 2/2] Add missing test case. --- authority/provisioner/provisioner_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/authority/provisioner/provisioner_test.go b/authority/provisioner/provisioner_test.go index 39ce2e2e..bf99aa76 100644 --- a/authority/provisioner/provisioner_test.go +++ b/authority/provisioner/provisioner_test.go @@ -109,6 +109,13 @@ func TestDefaultIdentityFunc(t *testing.T) { identity: &Identity{Usernames: []string{"john", "John@smallstep.com"}}, } }, + "ok symbol": func(t *testing.T) test { + return test{ + p: &OIDC{}, + email: "John+Doe@smallstep.com", + identity: &Identity{Usernames: []string{"john_doe", "John+Doe", "John+Doe@smallstep.com"}}, + } + }, } for name, get := range tests { t.Run(name, func(t *testing.T) {