fly: behavior: add validation for empty auth config

improved the way auth config for teams are validated. Now operators cannot start a web node with an empty
`--main-team-config` file, and `fly set-team` will fail if it would result in a team with no possible members.
This prevents scenarios where users can get accidentally locked out.

concourse/concourse#5595

Signed-off-by: Syamala Umamaheswaran <shyam@oss.volkswagen.com>

Co-authored-by: Lukas Benedix <lbenedix@oss.volkswagen.com>
This commit is contained in:
Syamala Umamaheswaran 2020-05-20 17:50:47 +02:00
parent 22251322f1
commit 102ed6e94b
No known key found for this signature in database
GPG Key ID: 9B570FA7BA2064BC
5 changed files with 16 additions and 34 deletions

View File

@ -1496,7 +1496,7 @@ func (cmd *RunCommand) configureAuthForDefaultTeam(teamFactory db.TeamFactory) e
return fmt.Errorf("default team auth not configured: %v", err)
}
err = team.UpdateProviderAuth(atc.TeamAuth(auth))
err = team.UpdateProviderAuth(auth)
if err != nil {
return err
}

View File

@ -5,8 +5,8 @@ import (
)
var (
ErrAuthConfigEmpty = errors.New("auth config must not be empty")
ErrAuthConfigInvalid = errors.New("users and groups are not provided for a specified role")
ErrAuthConfigEmpty = errors.New("auth config for the team must not be empty")
ErrAuthConfigInvalid = errors.New("auth config for the team does not have users and groups configured")
)
type Team struct {

View File

@ -43,7 +43,7 @@ func (command *SetTeamCommand) Execute([]string) error {
authRoles, err := command.AuthFlags.Format()
if err != nil {
command.ErrorAuthNotConfigured(err)
fmt.Fprintln(ui.Stderr, "error:", err)
os.Exit(1)
}
@ -95,7 +95,7 @@ func (command *SetTeamCommand) Execute([]string) error {
displayhelpers.Failf("bailing out")
}
team := atc.Team{Auth: atc.TeamAuth(authRoles)}
team := atc.Team{Auth: authRoles}
_, created, updated, err := target.Client().Team(teamName).CreateOrUpdate(team)
if err != nil {
@ -110,16 +110,3 @@ func (command *SetTeamCommand) Execute([]string) error {
return nil
}
func (command *SetTeamCommand) ErrorAuthNotConfigured(err error) {
switch err {
case skycmd.ErrAuthNotConfiguredFromFile:
fmt.Fprintln(ui.Stderr, "You have not provided a list of users and groups for one of the roles in your config yaml.")
case skycmd.ErrAuthNotConfiguredFromFlags:
fmt.Fprintln(ui.Stderr, "You have not provided users and groups for the specified team.")
default:
fmt.Fprintln(ui.Stderr, "error:", err)
}
}

View File

@ -472,7 +472,7 @@ var _ = Describe("Fly CLI", func() {
It("returns an error", func() {
sess, err := gexec.Start(flyCmd, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(sess.Err).Should(gbytes.Say("You have not provided users and groups for the specified team."))
Eventually(sess.Err).Should(gbytes.Say("auth config for the team does not have users and groups configured"))
Eventually(sess).Should(gexec.Exit(1))
})
})
@ -485,7 +485,7 @@ var _ = Describe("Fly CLI", func() {
It("returns an error", func() {
sess, err := gexec.Start(flyCmd, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(sess.Err).Should(gbytes.Say("You have not provided users and groups for the specified team."))
Eventually(sess.Err).Should(gbytes.Say("auth config for the team does not have users and groups configured"))
Eventually(sess).Should(gexec.Exit(1))
})
})
@ -498,7 +498,7 @@ var _ = Describe("Fly CLI", func() {
It("returns an error", func() {
sess, err := gexec.Start(flyCmd, ginkgo.GinkgoWriter, ginkgo.GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(sess.Err).Should(gbytes.Say("You have not provided a list of users and groups for one of the roles in your config yaml."))
Eventually(sess.Err).Should(gbytes.Say("auth config for the team must not be empty"))
Eventually(sess).Should(gexec.Exit(1))
})
})

View File

@ -16,9 +16,6 @@ import (
"github.com/concourse/flag"
)
var ErrAuthNotConfiguredFromFlags = errors.New("ErrAuthNotConfiguredFromFlags")
var ErrAuthNotConfiguredFromFile = errors.New("ErrAuthNotConfiguredFromFile")
var connectors []*Connector
func RegisterConnector(connector *Connector) {
@ -58,7 +55,7 @@ type AuthTeamFlags struct {
Config flag.File `short:"c" long:"config" description:"Configuration file for specifying team params"`
}
func (flag *AuthTeamFlags) Format() (AuthConfig, error) {
func (flag *AuthTeamFlags) Format() (atc.TeamAuth, error) {
if path := flag.Config.Path(); path != "" {
return flag.formatFromFile()
@ -77,7 +74,7 @@ func (flag *AuthTeamFlags) Format() (AuthConfig, error) {
// The github connector has configuration for: users, teams, orgs
// The cf conncetor has configuration for: users, orgs, spaces
func (flag *AuthTeamFlags) formatFromFile() (AuthConfig, error) {
func (flag *AuthTeamFlags) formatFromFile() (atc.TeamAuth, error) {
content, err := ioutil.ReadFile(flag.Config.Path())
if err != nil {
@ -91,7 +88,7 @@ func (flag *AuthTeamFlags) formatFromFile() (AuthConfig, error) {
return nil, err
}
auth := AuthConfig{}
auth := atc.TeamAuth{}
for _, role := range data.Roles {
roleName := role["name"].(string)
@ -146,8 +143,8 @@ func (flag *AuthTeamFlags) formatFromFile() (AuthConfig, error) {
}
}
if err := atc.TeamAuth(auth).Validate(); err != nil {
return nil, ErrAuthNotConfiguredFromFile
if err := auth.Validate(); err != nil {
return nil, err
}
return auth, nil
@ -157,7 +154,7 @@ func (flag *AuthTeamFlags) formatFromFile() (AuthConfig, error) {
// TeamConfig has already been populated by the flags library. All we need to
// do is grab the teamConfig object and extract the users and groups.
func (flag *AuthTeamFlags) formatFromFlags() (AuthConfig, error) {
func (flag *AuthTeamFlags) formatFromFlags() (atc.TeamAuth, error) {
users := []string{}
groups := []string{}
@ -186,10 +183,10 @@ func (flag *AuthTeamFlags) formatFromFlags() (AuthConfig, error) {
}
if len(users) == 0 && len(groups) == 0 {
return nil, ErrAuthNotConfiguredFromFlags
return nil, atc.ErrAuthConfigInvalid
}
return AuthConfig{
return atc.TeamAuth{
"owner": map[string][]string{
"users": users,
"groups": groups,
@ -245,5 +242,3 @@ func (con *Connector) newTeamConfig() (TeamConfig, error) {
return res, nil
}
type AuthConfig map[string]map[string][]string