mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
chore: Implement standard rbac.Subject to be reused everywhere (#5881)
* chore: Implement standard rbac.Subject to be reused everywhere An rbac subject is created in multiple spots because of the way we expand roles, scopes, etc. This difference in use creates a list of arguments which is unwieldy. Use of the expander interface lets us conform to a single subject in every case
This commit is contained in:
@ -52,11 +52,10 @@ func APIKey(r *http.Request) database.APIKey {
|
||||
type userAuthKey struct{}
|
||||
|
||||
type Authorization struct {
|
||||
ID uuid.UUID
|
||||
Actor rbac.Subject
|
||||
// Username is required for logging and human friendly related
|
||||
// identification.
|
||||
Username string
|
||||
Roles rbac.RoleNames
|
||||
Groups []string
|
||||
Scope database.APIKeyScope
|
||||
}
|
||||
|
||||
// UserAuthorizationOptional may return the roles and scope used for
|
||||
@ -343,11 +342,13 @@ func ExtractAPIKey(cfg ExtractAPIKeyConfig) func(http.Handler) http.Handler {
|
||||
|
||||
ctx = context.WithValue(ctx, apiKeyContextKey{}, key)
|
||||
ctx = context.WithValue(ctx, userAuthKey{}, Authorization{
|
||||
ID: key.UserID,
|
||||
Username: roles.Username,
|
||||
Roles: roles.Roles,
|
||||
Scope: key.Scope,
|
||||
Groups: roles.Groups,
|
||||
Actor: rbac.Subject{
|
||||
ID: key.UserID.String(),
|
||||
Roles: rbac.RoleNames(roles.Roles),
|
||||
Groups: roles.Groups,
|
||||
Scope: rbac.ScopeName(key.Scope),
|
||||
},
|
||||
})
|
||||
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
|
@ -126,8 +126,8 @@ func TestExtractUserRoles(t *testing.T) {
|
||||
)
|
||||
rtr.Get("/", func(_ http.ResponseWriter, r *http.Request) {
|
||||
roles := httpmw.UserAuthorization(r)
|
||||
require.ElementsMatch(t, user.ID, roles.ID)
|
||||
require.ElementsMatch(t, expRoles, roles.Roles)
|
||||
require.Equal(t, user.ID.String(), roles.Actor.ID)
|
||||
require.ElementsMatch(t, expRoles, roles.Actor.Roles.Names())
|
||||
})
|
||||
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
|
@ -47,7 +47,7 @@ func RateLimit(count int, window time.Duration) func(http.Handler) http.Handler
|
||||
|
||||
// We avoid using rbac.Authorizer since rego is CPU-intensive
|
||||
// and undermines the DoS-prevention goal of the rate limiter.
|
||||
for _, role := range auth.Roles {
|
||||
for _, role := range auth.Actor.SafeRoleNames() {
|
||||
if role == rbac.RoleOwner() {
|
||||
// HACK: use a random key each time to
|
||||
// de facto disable rate limiting. The
|
||||
|
Reference in New Issue
Block a user