-
Notifications
You must be signed in to change notification settings - Fork 894
feat: add session actor middleware #897
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
f868929
ada9c1a
999c197
6f7b7d4
1cf0c58
175aa8c
cb9ec1e
efcee3d
4c9dd06
5bea2cb
dadef23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package session | ||
|
||
import ( | ||
"github.com/coder/coder/coderd/database" | ||
) | ||
|
||
// ActorType is an enum of all types of Actors. | ||
type ActorType string | ||
|
||
// ActorTypes. | ||
const ( | ||
ActorTypeSystem ActorType = "system" | ||
ActorTypeAnonymous ActorType = "anonymous" | ||
deansheather marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ActorTypeUser ActorType = "user" | ||
) | ||
|
||
// Actor represents an unauthenticated or authenticated client accessing the | ||
// API. To check authorization, callers should call pass the Actor into the | ||
// authz package to assert access. | ||
type Actor interface { | ||
Type() ActorType | ||
deansheather marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// ID is the unique ID of the actor for logging purposes. | ||
ID() string | ||
// Name is a friendly, but consistent, name for the actor for logging | ||
// purposes. E.g. "deansheather" | ||
Name() string | ||
Comment on lines
+25
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't this either be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On each request I want to log the actor name at least, so it's easy to see which user made a request in the logs. I am removing the SystemActor though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this ok @kylecarbs? The goal of this is so we can log the username without having to do a type cast because of the same reason as above (type switching just to read the username is very slow). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're just going to have the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're not just going to have the UserActor type. We will also have a WorkspaceActor and eventually a SatelliteActor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we just have two or three though, could we just log the username / workspace / satellite name separately? If the actor type is primarily going to be used for that, I'm hesitant to say it's worth the grouping. I'd think we'd have separate routes for users / workspaces / satellites anyways, similar to how agents can only access specific routes right now. In that pattern, there's no opportunity to have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is one way to separate things. But that makes each actor type more distinct. RBAC means an agent token is just a I see value in the separating routes approach too. Both options require their own care. One thing I wonder about is will a |
||
|
||
// TODO: Steven - RBAC methods | ||
deansheather marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// ActorTypeSystem represents the system making an authenticated request against | ||
// itself. This should be used if a function requires an Actor but you need to | ||
// skip authorization. | ||
type SystemActor interface { | ||
Actor | ||
System() | ||
} | ||
|
||
// AnonymousActor represents an unauthenticated API client. | ||
type AnonymousActor interface { | ||
Actor | ||
Anonymous() | ||
} | ||
|
||
// UserActor represents an authenticated user actor. Any consumers that wish to | ||
// check if the actor is a user (and access user fields such as User.ID) can | ||
// do a checked type cast from Actor to UserActor. | ||
type UserActor interface { | ||
Actor | ||
User() *database.User | ||
} | ||
deansheather marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package session | ||
|
||
type anonymousActor struct{} | ||
|
||
// Anon is a static AnonymousActor implementation. | ||
var Anon AnonymousActor = anonymousActor{} | ||
|
||
func (anonymousActor) Type() ActorType { | ||
return ActorTypeAnonymous | ||
} | ||
|
||
func (anonymousActor) ID() string { | ||
return "anon" | ||
} | ||
|
||
func (anonymousActor) Name() string { | ||
return "anonymous" | ||
} | ||
|
||
func (anonymousActor) Anonymous() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// Package session provides session authentication via middleware for the Coder | ||
// HTTP API. It also exposes the Actor type, which is the intermediary layer | ||
// between identity and RBAC authorization. | ||
deansheather marked this conversation as resolved.
Show resolved
Hide resolved
|
||
package session |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package session | ||
|
||
type systemActor struct{} | ||
|
||
// System is a static SystemActor implementation. | ||
var System SystemActor = systemActor{} | ||
|
||
func (systemActor) Type() ActorType { | ||
return ActorTypeSystem | ||
} | ||
|
||
func (systemActor) ID() string { | ||
return "system" | ||
} | ||
|
||
func (systemActor) Name() string { | ||
return "system" | ||
} | ||
|
||
func (systemActor) System() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package session | ||
|
||
import "github.com/coder/coder/coderd/database" | ||
|
||
type userActor struct { | ||
user *database.User | ||
} | ||
|
||
var _ UserActor = &userActor{} | ||
|
||
func NewUserActor(u *database.User) UserActor { | ||
return &userActor{ | ||
user: u, | ||
} | ||
} | ||
|
||
func (*userActor) Type() ActorType { | ||
return ActorTypeUser | ||
} | ||
|
||
func (ua *userActor) ID() string { | ||
return ua.user.ID.String() | ||
} | ||
|
||
func (ua *userActor) Name() string { | ||
return ua.user.Username | ||
} | ||
|
||
func (ua *userActor) User() *database.User { | ||
return ua.user | ||
} |
Uh oh!
There was an error while loading. Please reload this page.