mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-27 05:49:04 +01:00
Add new role support. This enables designated users to see all jobs.
This commit is contained in:
parent
a0dafbac99
commit
84bac7e520
@ -142,7 +142,7 @@ func main() {
|
|||||||
flag.BoolVar(&flagStopImmediately, "no-server", false, "Do not start a server, stop right after initialization and argument handling")
|
flag.BoolVar(&flagStopImmediately, "no-server", false, "Do not start a server, stop right after initialization and argument handling")
|
||||||
flag.BoolVar(&flagGops, "gops", false, "Listen via github.com/google/gops/agent (for debugging)")
|
flag.BoolVar(&flagGops, "gops", false, "Listen via github.com/google/gops/agent (for debugging)")
|
||||||
flag.StringVar(&flagConfigFile, "config", "./config.json", "Overwrite the global config options by those specified in `config.json`")
|
flag.StringVar(&flagConfigFile, "config", "./config.json", "Overwrite the global config options by those specified in `config.json`")
|
||||||
flag.StringVar(&flagNewUser, "add-user", "", "Add a new user. Argument format: `<username>:[admin,api,user]:<password>`")
|
flag.StringVar(&flagNewUser, "add-user", "", "Add a new user. Argument format: `<username>:[admin,support,api,user]:<password>`")
|
||||||
flag.StringVar(&flagDelUser, "del-user", "", "Remove user by `username`")
|
flag.StringVar(&flagDelUser, "del-user", "", "Remove user by `username`")
|
||||||
flag.StringVar(&flagGenJWT, "jwt", "", "Generate and print a JWT for the user specified by its `username`")
|
flag.StringVar(&flagGenJWT, "jwt", "", "Generate and print a JWT for the user specified by its `username`")
|
||||||
flag.StringVar(&flagImportJob, "import-job", "", "Import a job. Argument format: `<path-to-meta.json>:<path-to-data.json>,...`")
|
flag.StringVar(&flagImportJob, "import-job", "", "Import a job. Argument format: `<path-to-meta.json>:<path-to-data.json>,...`")
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
RoleAdmin string = "admin"
|
RoleAdmin string = "admin"
|
||||||
|
RoleSupport string = "support"
|
||||||
RoleApi string = "api"
|
RoleApi string = "api"
|
||||||
RoleUser string = "user"
|
RoleUser string = "user"
|
||||||
)
|
)
|
||||||
|
@ -112,7 +112,7 @@ func (auth *Authentication) AddRole(ctx context.Context, username string, role s
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if role != RoleAdmin && role != RoleApi && role != RoleUser {
|
if role != RoleAdmin && role != RoleApi && role != RoleUser && role != RoleSupport {
|
||||||
return fmt.Errorf("invalid user role: %#v", role)
|
return fmt.Errorf("invalid user role: %#v", role)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ func (auth *Authentication) AddRole(ctx context.Context, username string, role s
|
|||||||
|
|
||||||
func FetchUser(ctx context.Context, db *sqlx.DB, username string) (*model.User, error) {
|
func FetchUser(ctx context.Context, db *sqlx.DB, username string) (*model.User, error) {
|
||||||
me := GetUser(ctx)
|
me := GetUser(ctx)
|
||||||
if me != nil && !me.HasRole(RoleAdmin) && me.Username != username {
|
if me != nil && !me.HasRole(RoleAdmin) && !me.HasRole(RoleSupport) && me.Username != username {
|
||||||
return nil, errors.New("forbidden")
|
return nil, errors.New("forbidden")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ func (r *queryResolver) Job(ctx context.Context, id string) (*schema.Job, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if user := auth.GetUser(ctx); user != nil && !user.HasRole(auth.RoleAdmin) && job.User != user.Username {
|
if user := auth.GetUser(ctx); user != nil && !user.HasRole(auth.RoleAdmin) && !user.HasRole(auth.RoleSupport) && job.User != user.Username {
|
||||||
return nil, errors.New("you are not allowed to see this job")
|
return nil, errors.New("you are not allowed to see this job")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +309,7 @@ func (r *JobRepository) FindJobOrUser(ctx context.Context, searchterm string) (j
|
|||||||
user := auth.GetUser(ctx)
|
user := auth.GetUser(ctx)
|
||||||
if id, err := strconv.Atoi(searchterm); err == nil {
|
if id, err := strconv.Atoi(searchterm); err == nil {
|
||||||
qb := sq.Select("job.id").From("job").Where("job.job_id = ?", id)
|
qb := sq.Select("job.id").From("job").Where("job.job_id = ?", id)
|
||||||
if user != nil && !user.HasRole(auth.RoleAdmin) {
|
if user != nil && !user.HasRole(auth.RoleAdmin) && !user.HasRole(auth.RoleSupport) {
|
||||||
qb = qb.Where("job.user = ?", user.Username)
|
qb = qb.Where("job.user = ?", user.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ func (r *JobRepository) FindJobOrUser(ctx context.Context, searchterm string) (j
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if user == nil || user.HasRole(auth.RoleAdmin) {
|
if user == nil || user.HasRole(auth.RoleAdmin) || user.HasRole(auth.RoleSupport) {
|
||||||
err := sq.Select("job.user").Distinct().From("job").
|
err := sq.Select("job.user").Distinct().From("job").
|
||||||
Where("job.user = ?", searchterm).
|
Where("job.user = ?", searchterm).
|
||||||
RunWith(r.stmtCache).QueryRow().Scan(&username)
|
RunWith(r.stmtCache).QueryRow().Scan(&username)
|
||||||
|
@ -94,7 +94,7 @@ func (r *JobRepository) CountJobs(
|
|||||||
|
|
||||||
func SecurityCheck(ctx context.Context, query sq.SelectBuilder) sq.SelectBuilder {
|
func SecurityCheck(ctx context.Context, query sq.SelectBuilder) sq.SelectBuilder {
|
||||||
user := auth.GetUser(ctx)
|
user := auth.GetUser(ctx)
|
||||||
if user == nil || user.HasRole(auth.RoleAdmin) || user.HasRole(auth.RoleApi) {
|
if user == nil || user.HasRole(auth.RoleAdmin) || user.HasRole(auth.RoleApi) || user.HasRole(auth.RoleSupport) {
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,15 +269,17 @@ func SetupRoutes(router *mux.Router) {
|
|||||||
title = strings.Replace(route.Title, "<ID>", id.(string), 1)
|
title = strings.Replace(route.Title, "<ID>", id.(string), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
username, isAdmin := "", true
|
username, isAdmin, isSupporter := "", true, true
|
||||||
|
|
||||||
if user := auth.GetUser(r.Context()); user != nil {
|
if user := auth.GetUser(r.Context()); user != nil {
|
||||||
username = user.Username
|
username = user.Username
|
||||||
isAdmin = user.HasRole(auth.RoleAdmin)
|
isAdmin = user.HasRole(auth.RoleAdmin)
|
||||||
|
isSupporter = user.HasRole(auth.RoleSupport)
|
||||||
}
|
}
|
||||||
|
|
||||||
page := web.Page{
|
page := web.Page{
|
||||||
Title: title,
|
Title: title,
|
||||||
User: web.User{Username: username, IsAdmin: isAdmin},
|
User: web.User{Username: username, IsAdmin: isAdmin, IsSupporter: isSupporter},
|
||||||
Config: conf,
|
Config: conf,
|
||||||
Infos: infos,
|
Infos: infos,
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,10 @@
|
|||||||
<input type="radio" id="admin" name="role" value="admin"/>
|
<input type="radio" id="admin" name="role" value="admin"/>
|
||||||
<label for="admin">Admin</label>
|
<label for="admin">Admin</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="radio" id="support" name="role" value="support"/>
|
||||||
|
<label for="support">Support</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<code class="form-result"></code>
|
<code class="form-result"></code>
|
||||||
@ -131,6 +135,7 @@
|
|||||||
<option selected value="">Role...</option>
|
<option selected value="">Role...</option>
|
||||||
<option value="user">User</option>
|
<option value="user">User</option>
|
||||||
<option value="admin">Admin</option>
|
<option value="admin">Admin</option>
|
||||||
|
<option value="support">Support</option>
|
||||||
<option value="api">API</option>
|
<option value="api">API</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="btn btn-outline-secondary" type="button" id="add-role-button">Button</button>
|
<button class="btn btn-outline-secondary" type="button" id="add-role-button">Button</button>
|
||||||
|
@ -55,6 +55,7 @@ func init() {
|
|||||||
type User struct {
|
type User struct {
|
||||||
Username string // Username of the currently logged in user
|
Username string // Username of the currently logged in user
|
||||||
IsAdmin bool
|
IsAdmin bool
|
||||||
|
IsSupporter bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user