Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Use authorize filter in more places
  • Loading branch information
Emyrk committed May 23, 2022
commit bf74b4c38f242eda8cc0ed77528681cfe16b44cf
12 changes: 12 additions & 0 deletions coderd/database/modelmethods.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,15 @@ import "github.com/coder/coder/coderd/rbac"
func (t Template) RBACObject() rbac.Object {
return rbac.ResourceTemplate.InOrg(t.OrganizationID).WithID(t.ID.String())
}

func (w Workspace) RBACObject() rbac.Object {
return rbac.ResourceWorkspace.InOrg(w.OrganizationID).WithID(w.ID.String()).WithOwner(w.OwnerID.String())
}

func (m OrganizationMember) RBACObject() rbac.Object {
return rbac.ResourceOrganizationMember.InOrg(m.OrganizationID).WithID(m.UserID.String())
}

func (o Organization) RBACObject() rbac.Object {
return rbac.ResourceOrganization.InOrg(o.ID).WithID(o.ID.String())
}
26 changes: 8 additions & 18 deletions coderd/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func (api *api) userByName(rw http.ResponseWriter, r *http.Request) {
func (api *api) putUserProfile(rw http.ResponseWriter, r *http.Request) {
user := httpmw.UserParam(r)

if !api.Authorize(rw, r, rbac.ActionUpdate, rbac.ResourceUser.WithOwner(user.ID.String())) {
if !api.Authorize(rw, r, rbac.ActionUpdate, rbac.ResourceUser.WithID(user.ID.String())) {
return
}

Expand Down Expand Up @@ -389,7 +389,6 @@ func (api *api) putUserPassword(rw http.ResponseWriter, r *http.Request) {

func (api *api) userRoles(rw http.ResponseWriter, r *http.Request) {
user := httpmw.UserParam(r)
roles := httpmw.UserRoles(r)

if !api.Authorize(rw, r, rbac.ActionRead, rbac.ResourceUserData.
WithOwner(user.ID.String())) {
Expand All @@ -409,13 +408,10 @@ func (api *api) userRoles(rw http.ResponseWriter, r *http.Request) {
return
}

for _, mem := range memberships {
err := api.Authorizer.ByRoleName(r.Context(), roles.ID.String(), roles.Roles, rbac.ActionRead,
rbac.ResourceOrganizationMember.
WithID(user.ID.String()).
InOrg(mem.OrganizationID),
)
// Only include ones we can read from RBAC
memberships = AuthorizeFilter(api, r, rbac.ActionRead, memberships)

for _, mem := range memberships {
// If we can read the org member, include the roles
if err == nil {
resp.OrganizationRoles[mem.OrganizationID] = mem.Roles
Expand Down Expand Up @@ -508,7 +504,6 @@ func (api *api) updateSiteUserRoles(ctx context.Context, args database.UpdateUse
// Returns organizations the parameterized user has access to.
func (api *api) organizationsByUser(rw http.ResponseWriter, r *http.Request) {
user := httpmw.UserParam(r)
roles := httpmw.UserRoles(r)

organizations, err := api.Database.GetOrganizationsByUserID(r.Context(), user.ID)
if errors.Is(err, sql.ErrNoRows) {
Expand All @@ -522,17 +517,12 @@ func (api *api) organizationsByUser(rw http.ResponseWriter, r *http.Request) {
return
}

// Only return orgs the user can read
organizations = AuthorizeFilter(api, r, rbac.ActionRead, organizations)

publicOrganizations := make([]codersdk.Organization, 0, len(organizations))
for _, organization := range organizations {
err := api.Authorizer.ByRoleName(r.Context(), roles.ID.String(), roles.Roles, rbac.ActionRead,
rbac.ResourceOrganization.
WithID(organization.ID.String()).
InOrg(organization.ID),
)
if err == nil {
// Only return orgs the user can read
publicOrganizations = append(publicOrganizations, convertOrganization(organization))
}
publicOrganizations = append(publicOrganizations, convertOrganization(organization))
}

httpapi.Write(rw, http.StatusOK, publicOrganizations)
Expand Down
45 changes: 11 additions & 34 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ func (api *api) workspace(rw http.ResponseWriter, r *http.Request) {

func (api *api) workspacesByOrganization(rw http.ResponseWriter, r *http.Request) {
organization := httpmw.OrganizationParam(r)
roles := httpmw.UserRoles(r)
workspaces, err := api.Database.GetWorkspacesWithFilter(r.Context(), database.GetWorkspacesWithFilterParams{
OrganizationID: organization.ID,
Deleted: false,
Expand All @@ -123,17 +122,10 @@ func (api *api) workspacesByOrganization(rw http.ResponseWriter, r *http.Request
return
}

allowedWorkspaces := make([]database.Workspace, 0)
for _, ws := range workspaces {
ws := ws
err = api.Authorizer.ByRoleName(r.Context(), roles.ID.String(), roles.Roles, rbac.ActionRead,
rbac.ResourceWorkspace.InOrg(ws.OrganizationID).WithOwner(ws.OwnerID.String()).WithID(ws.ID.String()))
if err == nil {
allowedWorkspaces = append(allowedWorkspaces, ws)
}
}
// Rbac filter
workspaces = AuthorizeFilter(api, r, rbac.ActionRead, workspaces)

apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, allowedWorkspaces)
apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, workspaces)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("convert workspaces: %s", err),
Expand All @@ -146,7 +138,6 @@ func (api *api) workspacesByOrganization(rw http.ResponseWriter, r *http.Request
// workspaces returns all workspaces a user can read.
// Optional filters with query params
func (api *api) workspaces(rw http.ResponseWriter, r *http.Request) {
roles := httpmw.UserRoles(r)
apiKey := httpmw.APIKey(r)

// Empty strings mean no filter
Expand Down Expand Up @@ -186,24 +177,18 @@ func (api *api) workspaces(rw http.ResponseWriter, r *http.Request) {
filter.OwnerID = userID
}

allowedWorkspaces := make([]database.Workspace, 0)
allWorkspaces, err := api.Database.GetWorkspacesWithFilter(r.Context(), filter)
workspaces, err := api.Database.GetWorkspacesWithFilter(r.Context(), filter)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get workspaces for user: %s", err),
})
return
}
for _, ws := range allWorkspaces {
ws := ws
err = api.Authorizer.ByRoleName(r.Context(), roles.ID.String(), roles.Roles, rbac.ActionRead,
rbac.ResourceWorkspace.InOrg(ws.OrganizationID).WithOwner(ws.OwnerID.String()).WithID(ws.ID.String()))
if err == nil {
allowedWorkspaces = append(allowedWorkspaces, ws)
}
}

apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, allowedWorkspaces)
// Only return workspaces the user can read
workspaces = AuthorizeFilter(api, r, rbac.ActionRead, workspaces)

apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, workspaces)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("convert workspaces: %s", err),
Expand All @@ -215,7 +200,6 @@ func (api *api) workspaces(rw http.ResponseWriter, r *http.Request) {

func (api *api) workspacesByOwner(rw http.ResponseWriter, r *http.Request) {
owner := httpmw.UserParam(r)
roles := httpmw.UserRoles(r)
workspaces, err := api.Database.GetWorkspacesWithFilter(r.Context(), database.GetWorkspacesWithFilterParams{
OwnerID: owner.ID,
Deleted: false,
Expand All @@ -230,17 +214,10 @@ func (api *api) workspacesByOwner(rw http.ResponseWriter, r *http.Request) {
return
}

allowedWorkspaces := make([]database.Workspace, 0)
for _, ws := range workspaces {
ws := ws
err = api.Authorizer.ByRoleName(r.Context(), roles.ID.String(), roles.Roles, rbac.ActionRead,
rbac.ResourceWorkspace.InOrg(ws.OrganizationID).WithOwner(ws.OwnerID.String()).WithID(ws.ID.String()))
if err == nil {
allowedWorkspaces = append(allowedWorkspaces, ws)
}
}
// Only return workspaces the user can read
workspaces = AuthorizeFilter(api, r, rbac.ActionRead, workspaces)

apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, allowedWorkspaces)
apiWorkspaces, err := convertWorkspaces(r.Context(), api.Database, workspaces)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("convert workspaces: %s", err),
Expand Down