Skip to content

Commit 3a4d061

Browse files
Move role package to auth/authz and create specific expored functions
for checking permissions Co-authored-by: Thomas Krampl <[email protected]>
1 parent 2c57eb7 commit 3a4d061

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+508
-466
lines changed

.configs/gqlgen.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ omit_root_models: true
2727
autobind:
2828
- "github.com/99designs/gqlgen/graphql/introspection" # Without this line in the beginning, a `prelude.resolver.go` is generated
2929
- "github.com/nais/api/internal/activitylog"
30+
- "github.com/nais/api/internal/auth/authz"
3031
- "github.com/nais/api/internal/cost"
3132
- "github.com/nais/api/internal/deployment"
3233
- "github.com/nais/api/internal/feature"
@@ -41,7 +42,6 @@ autobind:
4142
- "github.com/nais/api/internal/persistence/sqlinstance"
4243
- "github.com/nais/api/internal/persistence/valkey"
4344
- "github.com/nais/api/internal/reconciler"
44-
- "github.com/nais/api/internal/role/graphrole"
4545
- "github.com/nais/api/internal/search"
4646
- "github.com/nais/api/internal/serviceaccount"
4747
- "github.com/nais/api/internal/status"

.configs/sqlc.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,13 @@ sql:
6868
out: "../internal/team/teamsql"
6969

7070
- <<: *default_domain
71-
name: "Roles SQL"
72-
queries: "../internal/role/queries"
71+
name: "Authz SQL"
72+
queries: "../internal/auth/authz/queries"
7373
gen:
7474
go:
7575
<<: *default_go
76-
package: "rolesql"
77-
out: "../internal/role/rolesql"
76+
package: "authzsql"
77+
out: "../internal/auth/authz/authzsql"
7878

7979
- <<: *default_domain
8080
name: "Activity log SQL"

cmd/setup_local/main.go

+13-22
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
153153
ctx = activitylog.NewLoaderContext(ctx, pool)
154154
ctx = user.NewLoaderContext(ctx, pool)
155155
ctx = team.NewLoaderContext(ctx, pool, nil)
156-
ctx = role.NewLoaderContext(ctx, pool)
156+
ctx = authz.NewLoaderContext(ctx, pool)
157157
ctx = environment.NewLoaderContext(ctx, pool)
158158

159159
emails := map[string]struct{}{}
@@ -217,12 +217,6 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
217217
return fmt.Errorf("sync environments: %w", err)
218218
}
219219

220-
defaultUserRoles := []string{
221-
"Team creator",
222-
"Team viewer",
223-
"User viewer",
224-
}
225-
226220
var err error
227221
var adminUser, devUser *user.User
228222

@@ -233,7 +227,7 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
233227
return fmt.Errorf("create admin user: %w", err)
234228
}
235229
}
236-
if err := role.AssignGlobalRoleToUser(ctx, adminUser.UUID, "Admin"); err != nil {
230+
if err := authz.AssignGlobalAdmin(ctx, adminUser.UUID); err != nil {
237231
return fmt.Errorf("assign global admin role to admin user: %w", err)
238232
}
239233
actor := &authz.Actor{User: adminUser}
@@ -245,10 +239,9 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
245239
return fmt.Errorf("create dev user: %w", err)
246240
}
247241
}
248-
for _, roleName := range defaultUserRoles {
249-
if err := role.AssignGlobalRoleToUser(ctx, devUser.UUID, roleName); err != nil {
250-
return fmt.Errorf("assign globla role %q to dev user: %w", roleName, err)
251-
}
242+
243+
if err := authz.AssignDefaultPermissionsToUser(ctx, devUser.UUID); err != nil {
244+
return fmt.Errorf("assign default permissions to dev user: %w", err)
252245
}
253246

254247
users := []*user.User{devUser}
@@ -266,10 +259,8 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
266259
return fmt.Errorf("create user %q: %w", email, err)
267260
}
268261

269-
for _, roleName := range defaultUserRoles {
270-
if err = role.AssignGlobalRoleToUser(ctx, u.UUID, roleName); err != nil {
271-
return fmt.Errorf("assign global role %q to user %q: %w", roleName, u.Email, err)
272-
}
262+
if err = authz.AssignDefaultPermissionsToUser(ctx, u.UUID); err != nil {
263+
return fmt.Errorf("assign default permissions to user %q: %w", u.Email, err)
273264
}
274265

275266
log.Infof("%d/%d users created", i, *cfg.NumUsers)
@@ -302,8 +293,8 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
302293
return fmt.Errorf("update external references for devteam: %w", err)
303294
}
304295

305-
if err := role.AssignTeamRoleToUser(ctx, devUser.UUID, devteam.Slug, "Team owner"); err != nil {
306-
return fmt.Errorf("assign team owner role to dev user: %w", err)
296+
if err := authz.MakeUserTeamOwner(ctx, devUser.UUID, devteam.Slug); err != nil {
297+
return fmt.Errorf("make user %q owner of team %q: %w", devUser.Email, devteam.Slug, err)
307298
}
308299

309300
input := &team.UpdateTeamEnvironmentInput{
@@ -354,15 +345,15 @@ func run(ctx context.Context, cfg *seedConfig, log logrus.FieldLogger) error {
354345

355346
for o := 0; o < *cfg.NumOwnersPerTeam; o++ {
356347
u := users[rand.IntN(usersCreated)]
357-
if err = role.AssignTeamRoleToUser(ctx, u.UUID, t.Slug, "Team owner"); err != nil {
358-
return fmt.Errorf("assign team owner role to user %q in team %q: %w", u.Email, t.Slug, err)
348+
if err = authz.MakeUserTeamOwner(ctx, u.UUID, t.Slug); err != nil {
349+
return fmt.Errorf("make user %q owner of team %q: %w", u.Email, t.Slug, err)
359350
}
360351
}
361352

362353
for o := 0; o < *cfg.NumMembersPerTeam; o++ {
363354
u := users[rand.IntN(usersCreated)]
364-
if err = role.AssignTeamRoleToUser(ctx, u.UUID, t.Slug, "Team member"); err != nil {
365-
return fmt.Errorf("assign team member role to user %q in team %q: %w", u.Email, t.Slug, err)
355+
if err = authz.MakeUserTeamMember(ctx, u.UUID, t.Slug); err != nil {
356+
return fmt.Errorf("make user %q member of team %q: %w", u.Email, t.Slug, err)
366357
}
367358
}
368359

internal/role/authorizations.go internal/auth/authz/authorizations.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package role
1+
package authz
22

33
/*
44
type Authorization string
@@ -35,23 +35,23 @@ const (
3535
AuthorizationUnleashUpdate Authorization = "unleash:update"
3636
)
3737
38-
var roles = map[rolesql.RoleName][]Authorization{
39-
rolesql.RoleNameAdmin: {
38+
var roles = map[authzsql.RoleName][]Authorization{
39+
authzsql.RoleNameAdmin: {
4040
// Admins have all authorizations
4141
},
42-
rolesql.RoleNameTeamcreator: {
42+
authzsql.RoleNameTeamcreator: {
4343
AuthorizationTeamsCreate,
4444
},
45-
rolesql.RoleNameServiceaccountcreator: {
45+
authzsql.RoleNameServiceaccountcreator: {
4646
AuthorizationServiceAccountsCreate,
4747
},
48-
rolesql.RoleNameServiceaccountowner: {
48+
authzsql.RoleNameServiceaccountowner: {
4949
AuthorizationServiceAccountsCreate,
5050
AuthorizationServiceAccountsDelete,
5151
AuthorizationServiceAccountsRead,
5252
AuthorizationServiceAccountsUpdate,
5353
},
54-
rolesql.RoleNameTeammember: {
54+
authzsql.RoleNameTeammember: {
5555
AuthorizationActivityLogsRead,
5656
AuthorizationTeamsRead,
5757
AuthorizationTeamsMetadataUpdate,
@@ -76,7 +76,7 @@ var roles = map[rolesql.RoleName][]Authorization{
7676
AuthorizationServiceAccountsRead,
7777
AuthorizationServiceAccountsUpdate,
7878
},
79-
rolesql.RoleNameTeamowner: {
79+
authzsql.RoleNameTeamowner: {
8080
AuthorizationActivityLogsRead,
8181
AuthorizationTeamsDelete,
8282
AuthorizationTeamsRead,
@@ -103,22 +103,22 @@ var roles = map[rolesql.RoleName][]Authorization{
103103
AuthorizationServiceAccountsRead,
104104
AuthorizationServiceAccountsUpdate,
105105
},
106-
rolesql.RoleNameTeamviewer: {
106+
authzsql.RoleNameTeamviewer: {
107107
AuthorizationActivityLogsRead,
108108
AuthorizationTeamsList,
109109
AuthorizationTeamsRead,
110110
},
111-
rolesql.RoleNameUseradmin: {
111+
authzsql.RoleNameUseradmin: {
112112
AuthorizationUsersList,
113113
},
114-
rolesql.RoleNameUserviewer: {
114+
authzsql.RoleNameUserviewer: {
115115
AuthorizationUsersList,
116116
},
117-
rolesql.RoleNameSynchronizer: {
117+
authzsql.RoleNameSynchronizer: {
118118
AuthorizationTeamsSynchronize,
119119
AuthorizationUsersyncSynchronize,
120120
},
121-
rolesql.RoleNameDeploykeyviewer: {
121+
authzsql.RoleNameDeploykeyviewer: {
122122
AuthorizationDeployKeyRead,
123123
},
124124
}

internal/auth/authz/authz.go

+20-18
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ package authz
22

33
import (
44
"context"
5-
"errors"
65

76
"github.com/google/uuid"
8-
"github.com/nais/api/internal/role"
9-
"github.com/nais/api/internal/role/rolesql"
10-
"github.com/nais/api/internal/slug"
7+
"github.com/nais/api/internal/graph/apierror"
118
)
129

1310
type ContextKey string
@@ -20,10 +17,10 @@ type AuthenticatedUser interface {
2017

2118
type Actor struct {
2219
User AuthenticatedUser
23-
Roles []*role.Role
20+
Roles []*Role
2421
}
2522

26-
var ErrNotAuthenticated = errors.New("not authenticated")
23+
var ErrNotAuthenticated = apierror.Errorf("Valid user required. You are not logged in.")
2724

2825
func (u *Actor) Authenticated() bool {
2926
if u == nil || u.User == nil {
@@ -36,7 +33,7 @@ func (u *Actor) Authenticated() bool {
3633
const contextKeyUser ContextKey = "actor"
3734

3835
// ContextWithActor Return a context with an actor attached to it.
39-
func ContextWithActor(ctx context.Context, user AuthenticatedUser, roles []*role.Role) context.Context {
36+
func ContextWithActor(ctx context.Context, user AuthenticatedUser, roles []*Role) context.Context {
4037
return context.WithValue(ctx, contextKeyUser, &Actor{
4138
User: user,
4239
Roles: roles,
@@ -50,19 +47,21 @@ func ActorFromContext(ctx context.Context) *Actor {
5047
return actor
5148
}
5249

53-
// RequireGlobalAuthorization Require an actor to have a specific authorization through a globally assigned role.
54-
func RequireGlobalAuthorization(actor *Actor, requiredAuthzName role.Authorization) error {
50+
/*
51+
// requireGlobalAuthorization Require an actor to have a specific authorization through a globally assigned role.
52+
func requireGlobalAuthorization(actor *Actor, requiredAuthzName string) error {
5553
if !actor.Authenticated() {
5654
return ErrNotAuthenticated
5755
}
5856
59-
authorizations := make(map[role.Authorization]struct{})
57+
authorizations := make(map[string]struct{})
6058
6159
for _, r := range actor.Roles {
62-
if r.Name == rolesql.RoleNameAdmin {
60+
if r.Name == "Admin" {
6361
return nil
6462
}
6563
64+
authorizations, err := ListAuthorizationsInRole(r.Name)
6665
roleAuthz, err := r.Authorizations()
6766
if err != nil {
6867
return err
@@ -77,17 +76,19 @@ func RequireGlobalAuthorization(actor *Actor, requiredAuthzName role.Authorizati
7776
return authorized(authorizations, requiredAuthzName)
7877
}
7978
80-
// RequireTeamAuthorization Require an actor to have a specific authorization through a globally assigned or a correctly
79+
80+
81+
// requireTeamAuthorization Require an actor to have a specific authorization through a globally assigned or a correctly
8182
// targeted role.
82-
func RequireTeamAuthorization(actor *Actor, requiredAuthzName role.Authorization, targetTeamSlug slug.Slug) error {
83+
func requireTeamAuthorization(actor *Actor, requiredAuthzName string, targetTeamSlug slug.Slug) error {
8384
if !actor.Authenticated() {
8485
return ErrNotAuthenticated
8586
}
8687
87-
authorizations := make(map[role.Authorization]struct{})
88+
authorizations := make(map[string]struct{})
8889
8990
for _, r := range actor.Roles {
90-
if r.Name == rolesql.RoleNameAdmin {
91+
if r.Name == "Admin" {
9192
return nil
9293
}
9394
@@ -106,12 +107,13 @@ func RequireTeamAuthorization(actor *Actor, requiredAuthzName role.Authorization
106107
}
107108
108109
// RequireTeamAuthorizationCtx fetches the actor from the context and checks if it has the required authorization.
109-
func RequireTeamAuthorizationCtx(ctx context.Context, requiredAuthzName role.Authorization, targetTeamSlug slug.Slug) error {
110+
func RequireTeamAuthorizationCtx(ctx context.Context, requiredAuthzName string, targetTeamSlug slug.Slug) error {
110111
return RequireTeamAuthorization(ActorFromContext(ctx), requiredAuthzName, targetTeamSlug)
111112
}
113+
*/
112114

113115
// authorized Check if one of the authorizations in the map matches the required authorization.
114-
func authorized(authorizations map[role.Authorization]struct{}, requiredAuthzName role.Authorization) error {
116+
func authorized(authorizations map[string]struct{}, requiredAuthzName string) error {
115117
for authorization := range authorizations {
116118
if authorization == requiredAuthzName {
117119
return nil
@@ -128,7 +130,7 @@ func RequireGlobalAdmin(ctx context.Context) error {
128130
}
129131

130132
for _, r := range actor.Roles {
131-
if r.Name == rolesql.RoleNameAdmin {
133+
if r.Name == "Admin" {
132134
return nil
133135
}
134136
}

0 commit comments

Comments
 (0)