Skip to content

feat: Implement list roles & enforce authorize examples #1273

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

Merged
merged 16 commits into from
May 3, 2022

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented May 3, 2022

This is the first step to enforcing rbac roles for our endpoints. This also adds the endpoints to list the roles available to assign.

@codecov
Copy link

codecov bot commented May 3, 2022

Codecov Report

Merging #1273 (c86c67c) into main (e530ab2) will increase coverage by 0.11%.
The diff coverage is 76.72%.

@@            Coverage Diff             @@
##             main    #1273      +/-   ##
==========================================
+ Coverage   65.96%   66.07%   +0.11%     
==========================================
  Files         277      280       +3     
  Lines       18230    18384     +154     
  Branches      216      216              
==========================================
+ Hits        12025    12147     +122     
- Misses       4956     4973      +17     
- Partials     1249     1264      +15     
Flag Coverage Δ
unittest-go-macos-latest 53.49% <73.58%> (+0.26%) ⬆️
unittest-go-postgres- 64.89% <76.72%> (+0.02%) ⬆️
unittest-go-ubuntu-latest 55.99% <73.58%> (+0.31%) ⬆️
unittest-go-windows-2022 51.92% <73.58%> (+0.27%) ⬆️
unittest-js 70.69% <ø> (ø)
Impacted Files Coverage Δ
coderd/rbac/object.go 100.00% <ø> (ø)
coderd/httpmw/authorize.go 68.18% <68.18%> (ø)
codersdk/roles.go 72.72% <72.72%> (ø)
coderd/rbac/builtin.go 92.42% <75.00%> (-3.88%) ⬇️
coderd/coderd.go 94.44% <87.09%> (-1.14%) ⬇️
coderd/database/queries.sql.go 78.10% <100.00%> (+0.06%) ⬆️
coderd/roles.go 100.00% <100.00%> (ø)
coderd/workspaceagents.go 56.04% <0.00%> (-2.80%) ⬇️
provisionerd/provisionerd.go 76.17% <0.00%> (-0.54%) ⬇️
coderd/provisionerdaemons.go 62.98% <0.00%> (-0.51%) ⬇️
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e530ab2...c86c67c. Read the comment docs.

@@ -48,6 +50,7 @@ type Options struct {
SecureAuthCookie bool
SSHKeygenAlgorithm gitsshkey.Algorithm
TURNServer *turnconn.Server
Authorizer *rbac.RegoAuthorizer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be exposed via options? It doesn't seem to be used outside of here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of making it an interface that is "denyall" or something to trigger in unit tests. But for now, we don't, so I'll drop it from Options

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah wait yes. @kylecarbs this will be needed if you decide to do the rbac Authorize() check manually inside the function, instead of the middleware. So this is required.

Copy link
Member

@kylecarbs kylecarbs May 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could go on api instead, that way tests couldn't mistakenly pass it via Options.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now nothing else is on the api only like that.

coder/coderd/coderd.go

Lines 333 to 338 in db04d67

type api struct {
*Options
websocketWaitMutex sync.Mutex
websocketWaitGroup sync.WaitGroup
}

I don't think it'd be bad to pass one in via options 🤷‍♂️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my bad, I thought there was precedent for this 🤦

If you feel like it's fine I'll defer, but I generally think it's hasty to expose a value unless it needs to be used elsewhere. It's really easy to expose a parameter, but much harder to hide one.

// Authorize will enforce if the user roles can complete the action on the AuthObject.
// The organization and owner are found using the ExtractOrganization and
// ExtractUser middleware if present.
func Authorize(logger slog.Logger, auth *rbac.RegoAuthorizer, action rbac.Action) func(http.Handler) http.Handler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authorize feels like action, not something that would return a handler.

What do you think about renaming this to EnforceRBAC?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think EnforceRBAC is also weak though. I was thinking the package httpmw provides enough context, and it does do the action Authorize().

Authorize is the correct word for what is happening, as it's not authentication. I feel EnforceRBAC doesn't indicate the object and action are included.

Another word that comes to mind is "Access". Idk, EnforceAccess, EnforcePermissions. Maybe EnforceRBAC isn't that bad, just felt odd to me at first.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. I'm primarily trying to display that the RBAC package is being leveraged when calling this handle. Enforce is a bit sketchy too.

While it is authorizing, I'm nervous that this will get conflated with authentication really easily.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea this is classic authorization vs authentication. If you aren't familiar with it, it's easy to mix up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed agreed

@Emyrk Emyrk requested a review from kylecarbs May 3, 2022 19:50

// WithRBACObject sets the object for 'Authorize()' for all routes handled
// by this middleware. The important field to set is 'Type'
func WithRBACObject(object rbac.Object) func(http.Handler) http.Handler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be confusing that this is called WithRBACObject, but the values are rbac.ResourceX. It could be helpful to make these the same names!

// Authorize will enforce if the user roles can complete the action on the AuthObject.
// The organization and owner are found using the ExtractOrganization and
// ExtractUser middleware if present.
func Authorize(logger slog.Logger, auth *rbac.RegoAuthorizer, action rbac.Action) func(http.Handler) http.Handler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed agreed

@Emyrk Emyrk merged commit d0293e4 into main May 3, 2022
@Emyrk Emyrk deleted the stevenmasley/list_roles branch May 3, 2022 21:10
@misskniss misskniss added this to the V2 Beta milestone May 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants