Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions internal/authorization/oidcbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (b *OIDCBuilder) GetUsernamePrefix() string {
}

func (b *OIDCBuilder) validate() error {
if b.repository == "" {
if b.repository == "" && b.requiredClaims["repository"] == "" {
return fmt.Errorf("repository can't be blank")
}
if !repositoryFormatValid(b.repository) {
Expand All @@ -108,9 +108,6 @@ func (b *OIDCBuilder) validate() error {
if b.issuerURL == "" {
return fmt.Errorf("issuerURL can't be blank")
}
if _, hasRepository := b.requiredClaims["repository"]; hasRepository {
return fmt.Errorf("required-claim key 'repository' is reserved and cannot be specified")
}

return nil
}
Expand Down
11 changes: 0 additions & 11 deletions internal/authorization/oidcbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,6 @@ func TestOIDCBuilder_Build_ValidationErrors(t *testing.T) {
},
expectedError: "repository can't be blank",
},
{
name: "invalid requiredClaim key - reserved 'repository' name",
setup: func() *authorization.OIDCBuilder {
return authorization.NewOIDCBuilder("test-client", "https://example.com").
ForRepository("some/repo").
ForRequiredClaims(map[string]string{
"repository": "some/other-repo",
})
},
expectedError: "required-claim key 'repository' is reserved and cannot be specified",
},
}

for _, tt := range tests {
Expand Down
15 changes: 9 additions & 6 deletions internal/cmd/alpha/authorize/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

type authorizeRepositoryConfig struct {
*cmdcommon.KymaConfig
repository string
clientId string
issuerURL string
prefix string
Expand Down Expand Up @@ -61,20 +60,23 @@ func NewAuthorizeRepositoryCMD(kymaConfig *cmdcommon.KymaConfig) *cobra.Command
kyma alpha authorize repository --repository kyma-project/cli --client-id repo-ci-client --role view --namespace dev --dry-run -o json`,
PreRun: func(cmd *cobra.Command, args []string) {
clierror.Check(flags.Validate(cmd.Flags(),
flags.MarkRequired("repository"),
flags.MarkRequired("client-id"),
flags.MarkExactlyOneRequired("role", "clusterrole"),
flags.MarkPrerequisites("role", "namespace"),
flags.MarkPrerequisites("cluster-wide", "clusterrole"),
))

if _, exists := cfg.requiredClaim.Values["repository"]; !exists {
clierror.Check(clierror.New(`required flag "repository" not set`))
}
},
Run: func(cmd *cobra.Command, args []string) {
clierror.Check(authorizeRepository(&cfg))
},
}

// Required flags
cmd.Flags().StringVar(&cfg.repository, "repository", "", "GitHub repo in owner/name format (e.g., kyma-project/cli) (required)")
cmd.Flags().Var(types.NewMapElem("repository", &cfg.requiredClaim), "repository", "GitHub repo in owner/name format (e.g., kyma-project/cli) (required)")
cmd.Flags().StringVar(&cfg.clientId, "client-id", "", "OIDC client ID (audience) expected in the token (required)")

// Optional flags with defaults
Expand All @@ -99,7 +101,7 @@ func authorizeRepository(cfg *authorizeRepositoryConfig) clierror.Error {
}

repositoryOIDCBuilder := authorization.NewOIDCBuilder(cfg.clientId, cfg.issuerURL).
ForRepository(cfg.repository).
ForRepository(requiredClaimsCasted["repository"]).
ForRequiredClaims(requiredClaimsCasted).
ForName(cfg.name).
ForPrefix(cfg.prefix)
Expand Down Expand Up @@ -138,8 +140,9 @@ func buildRBACResourceForRepository(cfg *authorizeRepositoryConfig, bindingPrefi
if err != nil {
return nil, clierror.Wrap(err, clierror.New("failed to generate binding"))
}
repository := fmt.Sprintf("%s", cfg.requiredClaim.Values["repository"])

sanitizedRepoName := strings.ReplaceAll(cfg.repository, "/", "-")
sanitizedRepoName := strings.ReplaceAll(repository, "/", "-")
var bindingName string
if cfg.role != "" {
bindingName = fmt.Sprintf("%s-%s-binding", sanitizedRepoName, cfg.role)
Expand All @@ -150,7 +153,7 @@ func buildRBACResourceForRepository(cfg *authorizeRepositoryConfig, bindingPrefi
builder := authorization.NewRBACBuilder().
ForPrefix(bindingPrefix).
ForSubjectKind(subjectKind).
ForSubjectName(cfg.repository).
ForSubjectName(repository).
ForBindingName(bindingName)

if cfg.clusterWide {
Expand Down
37 changes: 37 additions & 0 deletions internal/cmdcommon/types/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,43 @@ import (
"strings"
)

type MapElem struct {
key string
m *Map
}

func NewMapElem(key string, m *Map) *MapElem {
return &MapElem{
key: key,
m: m,
}
}

// Set implements the flag.Value interface
func (me *MapElem) Set(val string) error {
if me.m.Values == nil {
me.m.Values = map[string]interface{}{}
}
me.m.Values[me.key] = val
return nil
}

// String implements the flag.Value interface
func (me *MapElem) String() string {
if me.m == nil || me.m.Values == nil {
return ""
}
if v, ok := me.m.Values[me.key]; ok {
return fmt.Sprintf("%v", v)
}
return ""
}

// Type implements the pflag.Value interface
func (me *MapElem) Type() string {
return "string"
}

type Map struct {
Values map[string]interface{}
}
Expand Down