fix(commands): invalid opaque id service name (#3235)
This fixes the service type being openid_connect instead of openid as expected. This also allows bulk generating opaque identifiers for users.pull/3242/head
parent
861bcc898f
commit
06ba312c28
|
@ -113,5 +113,9 @@ var (
|
|||
)
|
||||
|
||||
const (
|
||||
identifierServiceOpenIDConnect = "openid_connect"
|
||||
identifierServiceOpenIDConnect = "openid"
|
||||
)
|
||||
|
||||
var (
|
||||
validIdentifierServices = []string{identifierServiceOpenIDConnect}
|
||||
)
|
||||
|
|
|
@ -71,6 +71,7 @@ func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
|||
cmd.AddCommand(
|
||||
newStorageUserIdentifiersExportCmd(),
|
||||
newStorageUserIdentifiersImportCmd(),
|
||||
newStorageUserIdentifiersGenerateCmd(),
|
||||
newStorageUserIdentifiersAddCmd(),
|
||||
)
|
||||
|
||||
|
@ -101,6 +102,20 @@ func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate opaque identifiers in bulk",
|
||||
RunE: storageUserIdentifiersGenerate,
|
||||
}
|
||||
|
||||
cmd.Flags().StringSlice("users", nil, "The list of users to generate the opaque identifiers for")
|
||||
cmd.Flags().StringSlice("services", []string{identifierServiceOpenIDConnect}, "The list of services to generate the opaque identifiers for, valid values are: openid")
|
||||
cmd.Flags().StringSlice("sectors", []string{""}, "The list of sectors to generate identifiers for")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
||||
cmd = &cobra.Command{
|
||||
Use: "add [username]",
|
||||
|
@ -110,7 +125,7 @@ func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
|||
}
|
||||
|
||||
cmd.Flags().String("identifier", "", "The optional version 4 UUID to use, if not set a random one will be used")
|
||||
cmd.Flags().String("service", identifierServiceOpenIDConnect, "The service to add the identifier for, valid values are: openid_connect")
|
||||
cmd.Flags().String("service", identifierServiceOpenIDConnect, "The service to add the identifier for, valid values are: openid")
|
||||
cmd.Flags().String("sector", "", "The sector identifier to use (should usually be blank)")
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/base32"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -759,6 +760,92 @@ func storageUserIdentifiersImport(cmd *cobra.Command, _ []string) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
func containsIdentifier(identifier model.UserOpaqueIdentifier, identifiers []model.UserOpaqueIdentifier) bool {
|
||||
for i := 0; i < len(identifiers); i++ {
|
||||
if identifier.Service == identifiers[i].Service && identifier.SectorID == identifiers[i].SectorID && identifier.Username == identifiers[i].Username {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func storageUserIdentifiersGenerate(cmd *cobra.Command, _ []string) (err error) {
|
||||
var (
|
||||
provider storage.Provider
|
||||
|
||||
ctx = context.Background()
|
||||
|
||||
users, services, sectors []string
|
||||
)
|
||||
|
||||
provider = getStorageProvider()
|
||||
|
||||
identifiers, err := provider.LoadUserOpaqueIdentifiers(ctx)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return fmt.Errorf("can't load the existing identifiers: %w", err)
|
||||
}
|
||||
|
||||
if users, err = cmd.Flags().GetStringSlice("users"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if services, err = cmd.Flags().GetStringSlice("services"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sectors, err = cmd.Flags().GetStringSlice("sectors"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
return fmt.Errorf("must supply at least one user")
|
||||
}
|
||||
|
||||
if len(sectors) == 0 {
|
||||
sectors = append(sectors, "")
|
||||
}
|
||||
|
||||
if !utils.IsStringSliceContainsAll(services, validIdentifierServices) {
|
||||
return fmt.Errorf("one or more the service names '%s' is invalid, the valid values are: '%s'", strings.Join(services, "', '"), strings.Join(validIdentifierServices, "', '"))
|
||||
}
|
||||
|
||||
var added, duplicates int
|
||||
|
||||
for _, service := range services {
|
||||
for _, sector := range sectors {
|
||||
for _, username := range users {
|
||||
identifier := model.UserOpaqueIdentifier{
|
||||
Service: service,
|
||||
SectorID: sector,
|
||||
Username: username,
|
||||
}
|
||||
|
||||
if containsIdentifier(identifier, identifiers) {
|
||||
duplicates++
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
identifier.Identifier, err = uuid.NewRandom()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate a uuid: %w", err)
|
||||
}
|
||||
|
||||
if err = provider.SaveUserOpaqueIdentifier(ctx, identifier); err != nil {
|
||||
return fmt.Errorf("failed to save identifier: %w", err)
|
||||
}
|
||||
|
||||
added++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully added %d opaque identifiers and %d duplicates were skipped\n", added, duplicates)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func storageUserIdentifiersAdd(cmd *cobra.Command, args []string) (err error) {
|
||||
var (
|
||||
provider storage.Provider
|
||||
|
@ -774,8 +861,8 @@ func storageUserIdentifiersAdd(cmd *cobra.Command, args []string) (err error) {
|
|||
|
||||
if service == "" {
|
||||
service = identifierServiceOpenIDConnect
|
||||
} else if service != identifierServiceOpenIDConnect {
|
||||
return fmt.Errorf("the service name '%s' is invalid, the valid values are: 'openid_connect'", service)
|
||||
} else if !utils.IsStringInSlice(service, validIdentifierServices) {
|
||||
return fmt.Errorf("the service name '%s' is invalid, the valid values are: '%s'", service, strings.Join(validIdentifierServices, "', '"))
|
||||
}
|
||||
|
||||
if sector, err = cmd.Flags().GetString("sector"); err != nil {
|
||||
|
|
|
@ -412,11 +412,11 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() {
|
|||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=webauthn", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: the service name 'webauthn' is invalid, the valid values are: 'openid_connect'")
|
||||
s.Assert().Contains(output, "Error: the service name 'webauthn' is invalid, the valid values are: 'openid'")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().NoError(err)
|
||||
s.Assert().Contains(output, "Added User Opaque Identifier:\n\tService: openid_connect\n\tSector: \n\tUsername: john\n\tIdentifier: 1097c8f8-83f2-4506-8138-5f40e83a1285\n\n")
|
||||
s.Assert().Contains(output, "Added User Opaque Identifier:\n\tService: openid\n\tSector: \n\tUsername: john\n\tIdentifier: 1097c8f8-83f2-4506-8138-5f40e83a1285\n\n")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=/a/no/path/fileout.yml", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
|
@ -434,27 +434,27 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() {
|
|||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: must specify a file that doesn't exist but '/tmp/out/1.yml' exists")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector=''", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: error inserting user opaque id for user 'john' with opaque id '1097c8f8-83f2-4506-8138-5f40e83a1285':")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector=''", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector=''", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: error inserting user opaque id for user 'john' with opaque id")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector='openidconnect.com'", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector='openidconnect.com'", "--identifier=1097c8f8-83f2-4506-8138-5f40e83a1285", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: error inserting user opaque id for user 'john' with opaque id '1097c8f8-83f2-4506-8138-5f40e83a1285':")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector='openidconnect.net'", "--identifier=b0e17f48-933c-4cba-8509-ee9bfadf8ce5", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector='openidconnect.net'", "--identifier=b0e17f48-933c-4cba-8509-ee9bfadf8ce5", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().NoError(err)
|
||||
s.Assert().Contains(output, "Added User Opaque Identifier:\n\tService: openid_connect\n\tSector: openidconnect.net\n\tUsername: john\n\tIdentifier: b0e17f48-933c-4cba-8509-ee9bfadf8ce5\n\n")
|
||||
s.Assert().Contains(output, "Added User Opaque Identifier:\n\tService: openid\n\tSector: openidconnect.net\n\tUsername: john\n\tIdentifier: b0e17f48-933c-4cba-8509-ee9bfadf8ce5\n\n")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector='bad-uuid.com'", "--identifier=d49564dc-b7a1-11ec-8429-fcaa147128ea", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector='bad-uuid.com'", "--identifier=d49564dc-b7a1-11ec-8429-fcaa147128ea", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: the identifier providerd 'd49564dc-b7a1-11ec-8429-fcaa147128ea' is a version 1 UUID but only version 4 UUID's accepted as identifiers")
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid_connect", "--sector='bad-uuid.com'", "--identifier=asdmklasdm", "--config=/config/configuration.storage.yml"})
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "add", "john", "--service=openid", "--sector='bad-uuid.com'", "--identifier=asdmklasdm", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().EqualError(err, "exit status 1")
|
||||
s.Assert().Contains(output, "Error: the identifier provided 'asdmklasdm' is invalid as it must be a version 4 UUID but parsing it had an error: invalid UUID length: 10")
|
||||
|
||||
|
@ -471,7 +471,7 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() {
|
|||
s.Assert().Equal("1097c8f8-83f2-4506-8138-5f40e83a1285", export.Identifiers[0].Identifier.String())
|
||||
s.Assert().Equal("john", export.Identifiers[0].Username)
|
||||
s.Assert().Equal("", export.Identifiers[0].SectorID)
|
||||
s.Assert().Equal("openid_connect", export.Identifiers[0].Service)
|
||||
s.Assert().Equal("openid", export.Identifiers[0].Service)
|
||||
|
||||
output, err = s.Exec("authelia-backend", []string{"authelia", s.testArg, s.coverageArg, "storage", "user", "identifiers", "export", "--file=/tmp/out/2.yml", "--config=/config/configuration.storage.yml"})
|
||||
s.Assert().NoError(err)
|
||||
|
@ -490,13 +490,13 @@ func (s *CLISuite) TestStorage04ShouldManageUniqueID() {
|
|||
s.Assert().Equal("1097c8f8-83f2-4506-8138-5f40e83a1285", export.Identifiers[0].Identifier.String())
|
||||
s.Assert().Equal("john", export.Identifiers[0].Username)
|
||||
s.Assert().Equal("", export.Identifiers[0].SectorID)
|
||||
s.Assert().Equal("openid_connect", export.Identifiers[0].Service)
|
||||
s.Assert().Equal("openid", export.Identifiers[0].Service)
|
||||
|
||||
s.Assert().Equal(2, export.Identifiers[1].ID)
|
||||
s.Assert().Equal("b0e17f48-933c-4cba-8509-ee9bfadf8ce5", export.Identifiers[1].Identifier.String())
|
||||
s.Assert().Equal("john", export.Identifiers[1].Username)
|
||||
s.Assert().Equal("openidconnect.net", export.Identifiers[1].SectorID)
|
||||
s.Assert().Equal("openid_connect", export.Identifiers[1].Service)
|
||||
s.Assert().Equal("openid", export.Identifiers[1].Service)
|
||||
}
|
||||
|
||||
func (s *CLISuite) TestStorage05ShouldChangeEncryptionKey() {
|
||||
|
|
Loading…
Reference in New Issue