Add initial implementation of grants
This commit is contained in:
parent
b8f1281f78
commit
69b6579de7
15 changed files with 308 additions and 73 deletions
123
internal/dis/component/auth/policy/grants.go
Normal file
123
internal/dis/component/auth/policy/grants.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package policy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoAccess = errors.New("no access")
|
||||
ErrInvalid = errors.New("invalid parameters")
|
||||
)
|
||||
|
||||
// Set sets a specific grant, overwriting a previous grant (if any)
|
||||
func (policy *Policy) Set(ctx context.Context, grant models.Grant) error {
|
||||
if grant.User == "" || grant.Slug == "" || grant.DrupalUsername == "" {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
// get the table
|
||||
table, err := policy.table(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// and create or update the given user / slug combination
|
||||
return table.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "user"}, {Name: "slug"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"drupal_user", "admin"}),
|
||||
}).Create(&grant).Error
|
||||
}
|
||||
|
||||
// Remove removes access for the given username form the given instance.
|
||||
// The user not having access is not an error.
|
||||
func (policy *Policy) Remove(ctx context.Context, username string, slug string) error {
|
||||
// empty username or slug never have acccess
|
||||
if username == "" || slug == "" {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
// get the table
|
||||
table, err := policy.table(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete the access from the database
|
||||
return table.Delete(&models.Grant{}, models.Grant{User: username, Slug: slug}).Error
|
||||
}
|
||||
|
||||
// User returns all grants for the given user
|
||||
func (policy *Policy) User(ctx context.Context, username string) (grants []models.Grant, err error) {
|
||||
if username == "" {
|
||||
return nil, ErrInvalid
|
||||
}
|
||||
|
||||
// get the table
|
||||
table, err := policy.table(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// find the grants
|
||||
err = table.Find(&grants, models.Grant{User: username}).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return grants, nil
|
||||
}
|
||||
|
||||
// Instance returns all the grants for the given instance
|
||||
func (policy *Policy) Instance(ctx context.Context, slug string) (grants []models.Grant, err error) {
|
||||
if slug == "" {
|
||||
return nil, ErrInvalid
|
||||
}
|
||||
|
||||
// get the table
|
||||
table, err := policy.table(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// find the grants
|
||||
err = table.Find(&grants, models.Grant{Slug: slug}).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return grants, nil
|
||||
}
|
||||
|
||||
// Has checks if the given username has access to the given instance.
|
||||
// If the user has access, returns the provided grant.
|
||||
//
|
||||
// If the user does not have access, returns ErrNoAccess.
|
||||
// Other errors may be returned in other cases.
|
||||
func (policy *Policy) Has(ctx context.Context, username string, slug string) (grant models.Grant, err error) {
|
||||
// empty username or slug never have acccess
|
||||
if username == "" || slug == "" {
|
||||
return grant, ErrInvalid
|
||||
}
|
||||
|
||||
// get the table
|
||||
table, err := policy.table(ctx)
|
||||
if err != nil {
|
||||
return grant, err
|
||||
}
|
||||
|
||||
// read the access from the database
|
||||
res := table.Find(&grant, models.Grant{User: username, Slug: slug})
|
||||
if err := res.Error; err != nil {
|
||||
return grant, err
|
||||
}
|
||||
|
||||
// if there were no rows affected, then there was no access granted
|
||||
if res.RowsAffected == 0 {
|
||||
return grant, ErrNoAccess
|
||||
}
|
||||
|
||||
// return the username and admin
|
||||
return grant, nil
|
||||
}
|
||||
1
internal/dis/component/auth/policy/info.go
Normal file
1
internal/dis/component/auth/policy/info.go
Normal file
|
|
@ -0,0 +1 @@
|
|||
package policy
|
||||
27
internal/dis/component/auth/policy/policy.go
Normal file
27
internal/dis/component/auth/policy/policy.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package policy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Policy struct {
|
||||
component.Base
|
||||
|
||||
Dependencies struct {
|
||||
SQL *sql.SQL
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
_ component.Provisionable = (*Policy)(nil)
|
||||
_ component.UserDeleteHook = (*Policy)(nil)
|
||||
)
|
||||
|
||||
func (pol *Policy) table(ctx context.Context) (*gorm.DB, error) {
|
||||
return pol.Dependencies.SQL.QueryTable(ctx, true, models.GrantTable)
|
||||
}
|
||||
30
internal/dis/component/auth/policy/purge.go
Normal file
30
internal/dis/component/auth/policy/purge.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package policy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||
)
|
||||
|
||||
func (*Policy) Provision(ctx context.Context, instance models.Instance, domain string) error {
|
||||
// component is purge-only
|
||||
return nil
|
||||
}
|
||||
|
||||
// Purge purges every policy for the given slug form the database
|
||||
func (pol *Policy) Purge(ctx context.Context, instance models.Instance, domain string) error {
|
||||
table, err := pol.table(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return table.Delete(&models.Grant{}, &models.Grant{Slug: instance.Slug}).Error
|
||||
}
|
||||
|
||||
// OnUserDelete is called when a user is deleted
|
||||
func (pol *Policy) OnUserDelete(ctx context.Context, user *models.User) error {
|
||||
table, err := pol.table(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return table.Delete(&models.Grant{}, &models.Grant{User: user.User}).Error
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue