GET license endpoint (#3651)

* GET license endpoint

Signed-off-by: Spike Curtis <spike@coder.com>

* SDK GetLicenses -> Licenses

Signed-off-by: Spike Curtis <spike@coder.com>

Signed-off-by: Spike Curtis <spike@coder.com>
This commit is contained in:
Spike Curtis
2022-08-24 11:44:22 -07:00
committed by GitHub
parent da54874958
commit c9bce19d88
13 changed files with 223 additions and 11 deletions

View File

@ -10,12 +10,12 @@ import (
"github.com/coder/coder/coderd/rbac"
)
func AuthorizeFilter[O rbac.Objecter](api *API, r *http.Request, action rbac.Action, objects []O) ([]O, error) {
func AuthorizeFilter[O rbac.Objecter](h *HTTPAuthorizer, r *http.Request, action rbac.Action, objects []O) ([]O, error) {
roles := httpmw.AuthorizationUserRoles(r)
objects, err := rbac.Filter(r.Context(), api.Authorizer, roles.ID.String(), roles.Roles, action, objects)
objects, err := rbac.Filter(r.Context(), h.Authorizer, roles.ID.String(), roles.Roles, action, objects)
if err != nil {
// Log the error as Filter should not be erroring.
api.Logger.Error(r.Context(), "filter failed",
h.Logger.Error(r.Context(), "filter failed",
slog.Error(err),
slog.F("user_id", roles.ID),
slog.F("username", roles.Username),

View File

@ -2278,8 +2278,8 @@ func (q *fakeQuerier) GetDeploymentID(_ context.Context) (string, error) {
func (q *fakeQuerier) InsertLicense(
_ context.Context, arg database.InsertLicenseParams) (database.License, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
q.mutex.Lock()
defer q.mutex.Unlock()
l := database.License{
ID: q.lastLicenseID + 1,
@ -2292,6 +2292,15 @@ func (q *fakeQuerier) InsertLicense(
return l, nil
}
func (q *fakeQuerier) GetLicenses(_ context.Context) ([]database.License, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
results := append([]database.License{}, q.licenses...)
sort.Slice(results, func(i, j int) bool { return results[i].ID < results[j].ID })
return results, nil
}
func (q *fakeQuerier) GetUserLinkByLinkedID(_ context.Context, id string) (database.UserLink, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()

View File

@ -43,3 +43,7 @@ func (f File) RBACObject() rbac.Object {
func (User) RBACObject() rbac.Object {
return rbac.ResourceUser
}
func (License) RBACObject() rbac.Object {
return rbac.ResourceLicense
}

View File

@ -36,6 +36,7 @@ type querier interface {
GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) (WorkspaceBuild, error)
GetLatestWorkspaceBuilds(ctx context.Context) ([]WorkspaceBuild, error)
GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceBuild, error)
GetLicenses(ctx context.Context) ([]License, error)
GetOrganizationByID(ctx context.Context, id uuid.UUID) (Organization, error)
GetOrganizationByName(ctx context.Context, name string) (Organization, error)
GetOrganizationIDsByMemberIDs(ctx context.Context, ids []uuid.UUID) ([]GetOrganizationIDsByMemberIDsRow, error)

View File

@ -475,6 +475,40 @@ func (q *sqlQuerier) UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyPar
return err
}
const getLicenses = `-- name: GetLicenses :many
SELECT id, uploaded_at, jwt, exp
FROM licenses
ORDER BY (id)
`
func (q *sqlQuerier) GetLicenses(ctx context.Context) ([]License, error) {
rows, err := q.db.QueryContext(ctx, getLicenses)
if err != nil {
return nil, err
}
defer rows.Close()
var items []License
for rows.Next() {
var i License
if err := rows.Scan(
&i.ID,
&i.UploadedAt,
&i.JWT,
&i.Exp,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const insertLicense = `-- name: InsertLicense :one
INSERT INTO
licenses (

View File

@ -7,3 +7,9 @@ INSERT INTO
)
VALUES
($1, $2, $3) RETURNING *;
-- name: GetLicenses :many
SELECT *
FROM licenses
ORDER BY (id);

View File

@ -50,7 +50,7 @@ func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
if daemons == nil {
daemons = []database.ProvisionerDaemon{}
}
daemons, err = AuthorizeFilter(api, r, rbac.ActionRead, daemons)
daemons, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, daemons)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching provisioner daemons.",

View File

@ -292,7 +292,7 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request)
}
// Filter templates based on rbac permissions
templates, err = AuthorizeFilter(api, r, rbac.ActionRead, templates)
templates, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, templates)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching templates.",

View File

@ -158,7 +158,7 @@ func (api *API) users(rw http.ResponseWriter, r *http.Request) {
return
}
users, err = AuthorizeFilter(api, r, rbac.ActionRead, users)
users, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, users)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching users.",
@ -503,7 +503,7 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) {
}
// Only include ones we can read from RBAC.
memberships, err = AuthorizeFilter(api, r, rbac.ActionRead, memberships)
memberships, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, memberships)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching memberships.",
@ -631,7 +631,7 @@ func (api *API) organizationsByUser(rw http.ResponseWriter, r *http.Request) {
}
// Only return orgs the user can read.
organizations, err = AuthorizeFilter(api, r, rbac.ActionRead, organizations)
organizations, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, organizations)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching organizations.",

View File

@ -143,7 +143,7 @@ func (api *API) workspaces(rw http.ResponseWriter, r *http.Request) {
}
// Only return workspaces the user can read
workspaces, err = AuthorizeFilter(api, r, rbac.ActionRead, workspaces)
workspaces, err = AuthorizeFilter(api.httpAuth, r, rbac.ActionRead, workspaces)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching workspaces.",