forked from TrueCloudLab/certificates
Draft: adding usernames to GetIdentityFunc
This commit is contained in:
parent
861ef80e0d
commit
bf364f0a5f
4 changed files with 9 additions and 12 deletions
|
@ -47,7 +47,7 @@ func WithDatabase(db db.AuthDB) Option {
|
||||||
|
|
||||||
// WithGetIdentityFunc sets a custom function to retrieve the identity from
|
// WithGetIdentityFunc sets a custom function to retrieve the identity from
|
||||||
// an external resource.
|
// an external resource.
|
||||||
func WithGetIdentityFunc(fn func(ctx context.Context, p provisioner.Interface, email string) (*provisioner.Identity, error)) Option {
|
func WithGetIdentityFunc(fn func(ctx context.Context, p provisioner.Interface, email string, usernames ...string) (*provisioner.Identity, error)) Option {
|
||||||
return func(a *Authority) error {
|
return func(a *Authority) error {
|
||||||
a.getIdentityFunc = fn
|
a.getIdentityFunc = fn
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -389,15 +389,10 @@ func (o *OIDC) AuthorizeSSHSign(ctx context.Context, token string) ([]SignOption
|
||||||
|
|
||||||
// Get the identity using either the default identityFunc or one injected
|
// Get the identity using either the default identityFunc or one injected
|
||||||
// externally.
|
// externally.
|
||||||
iden, err := o.getIdentityFunc(ctx, o, claims.Email)
|
iden, err := o.getIdentityFunc(ctx, o, claims.Email, claims.PreferredUsername)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
return nil, errs.Wrap(http.StatusInternalServerError, err, "oidc.AuthorizeSSHSign")
|
||||||
}
|
}
|
||||||
// Reuse the contains function provided for simplicity
|
|
||||||
if !containsAllMembers(iden.Usernames, []string{claims.PreferredUsername}) {
|
|
||||||
// Add preferred_username to the identity's Username
|
|
||||||
iden.Usernames = append(iden.Usernames, claims.PreferredUsername)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Certificate templates.
|
// Certificate templates.
|
||||||
data := sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames)
|
data := sshutil.CreateTemplateData(sshutil.UserCert, claims.Email, iden.Usernames)
|
||||||
|
|
|
@ -500,12 +500,13 @@ func TestOIDC_AuthorizeSSHSign(t *testing.T) {
|
||||||
assert.FatalError(t, p4.Init(config))
|
assert.FatalError(t, p4.Init(config))
|
||||||
assert.FatalError(t, p5.Init(config))
|
assert.FatalError(t, p5.Init(config))
|
||||||
|
|
||||||
p4.getIdentityFunc = func(ctx context.Context, p Interface, email string) (*Identity, error) {
|
p4.getIdentityFunc = func(ctx context.Context, p Interface, email string, usernames ...string) (*Identity, error) {
|
||||||
return &Identity{Usernames: []string{"max", "mariano"}}, nil
|
return &Identity{Usernames: []string{"max", "mariano"}}, nil
|
||||||
}
|
}
|
||||||
p5.getIdentityFunc = func(ctx context.Context, p Interface, email string) (*Identity, error) {
|
p5.getIdentityFunc = func(ctx context.Context, p Interface, email string, usernames ...string) (*Identity, error) {
|
||||||
return nil, errors.New("force")
|
return nil, errors.New("force")
|
||||||
}
|
}
|
||||||
|
// Additional test needed for empty usernames and duplicate email and usernames
|
||||||
|
|
||||||
t1, err := generateSimpleToken("the-issuer", p1.ClientID, &keys.Keys[0])
|
t1, err := generateSimpleToken("the-issuer", p1.ClientID, &keys.Keys[0])
|
||||||
assert.FatalError(t, err)
|
assert.FatalError(t, err)
|
||||||
|
|
|
@ -337,10 +337,10 @@ type Permissions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIdentityFunc is a function that returns an identity.
|
// GetIdentityFunc is a function that returns an identity.
|
||||||
type GetIdentityFunc func(ctx context.Context, p Interface, email string) (*Identity, error)
|
type GetIdentityFunc func(ctx context.Context, p Interface, email string, usernames ...string) (*Identity, error)
|
||||||
|
|
||||||
// DefaultIdentityFunc return a default identity depending on the provisioner type.
|
// DefaultIdentityFunc return a default identity depending on the provisioner type.
|
||||||
func DefaultIdentityFunc(ctx context.Context, p Interface, email string) (*Identity, error) {
|
func DefaultIdentityFunc(ctx context.Context, p Interface, email string, usernames ...string) (*Identity, error) {
|
||||||
switch k := p.(type) {
|
switch k := p.(type) {
|
||||||
case *OIDC:
|
case *OIDC:
|
||||||
// OIDC principals would be:
|
// OIDC principals would be:
|
||||||
|
@ -351,13 +351,14 @@ func DefaultIdentityFunc(ctx context.Context, p Interface, email string) (*Ident
|
||||||
if !sshUserRegex.MatchString(name) {
|
if !sshUserRegex.MatchString(name) {
|
||||||
return nil, errors.Errorf("invalid principal '%s' from email '%s'", name, email)
|
return nil, errors.Errorf("invalid principal '%s' from email '%s'", name, email)
|
||||||
}
|
}
|
||||||
usernames := []string{name}
|
usernames := append(usernames, name)
|
||||||
if i := strings.LastIndex(email, "@"); i >= 0 {
|
if i := strings.LastIndex(email, "@"); i >= 0 {
|
||||||
if local := email[:i]; !strings.EqualFold(local, name) {
|
if local := email[:i]; !strings.EqualFold(local, name) {
|
||||||
usernames = append(usernames, local)
|
usernames = append(usernames, local)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
usernames = append(usernames, email)
|
usernames = append(usernames, email)
|
||||||
|
// Some remove duplicate function should be added
|
||||||
return &Identity{
|
return &Identity{
|
||||||
Usernames: usernames,
|
Usernames: usernames,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
Loading…
Reference in a new issue