fixed relationship issues
This commit is contained in:
@@ -2,7 +2,6 @@ package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"git.haelnorr.com/h/oslstats/internal/roles"
|
||||
"github.com/pkg/errors"
|
||||
@@ -10,42 +9,14 @@ import (
|
||||
)
|
||||
|
||||
type UserRole struct {
|
||||
bun.BaseModel `bun:"table:user_roles,alias:ur"`
|
||||
|
||||
ID int `bun:"id,pk,autoincrement"`
|
||||
UserID int `bun:"user_id,notnull"`
|
||||
RoleID int `bun:"role_id,notnull"`
|
||||
GrantedBy *int `bun:"granted_by"`
|
||||
GrantedAt int64 `bun:"granted_at,notnull"` // TODO: default now
|
||||
ExpiresAt *int64 `bun:"expires_at"`
|
||||
|
||||
// Relations
|
||||
User *User `bun:"rel:belongs-to,join:user_id=id"`
|
||||
Role *Role `bun:"rel:belongs-to,join:role_id=id"`
|
||||
}
|
||||
|
||||
// GetUserRoles loads all roles for a given user
|
||||
func GetUserRoles(ctx context.Context, tx bun.Tx, userID int) ([]*Role, error) {
|
||||
if userID <= 0 {
|
||||
return nil, errors.New("userID must be positive")
|
||||
}
|
||||
|
||||
var roles []*Role
|
||||
err := tx.NewSelect().
|
||||
Model(&roles).
|
||||
// TODO: why are we joining? can we do relation?
|
||||
Join("JOIN user_roles AS ur ON ur.role_id = r.id").
|
||||
Where("ur.user_id = ?", userID).
|
||||
Where("ur.expires_at IS NULL OR ur.expires_at > ?", time.Now().Unix()).
|
||||
Scan(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
return roles, nil
|
||||
UserID int `bun:",pk"`
|
||||
User *User `bun:"rel:belongs-to,join:user_id=id"`
|
||||
RoleID int `bun:",pk"`
|
||||
Role *Role `bun:"rel:belongs-to,join:role_id=id"`
|
||||
}
|
||||
|
||||
// AssignRole grants a role to a user
|
||||
func AssignRole(ctx context.Context, tx bun.Tx, userID, roleID int, grantedBy *int) error {
|
||||
func AssignRole(ctx context.Context, tx bun.Tx, userID, roleID int) error {
|
||||
if userID <= 0 {
|
||||
return errors.New("userID must be positive")
|
||||
}
|
||||
@@ -53,16 +24,16 @@ func AssignRole(ctx context.Context, tx bun.Tx, userID, roleID int, grantedBy *i
|
||||
return errors.New("roleID must be positive")
|
||||
}
|
||||
|
||||
now := time.Now().Unix()
|
||||
|
||||
// TODO: use proper m2m table instead of raw SQL
|
||||
_, err := tx.ExecContext(ctx, `
|
||||
INSERT INTO user_roles (user_id, role_id, granted_by, granted_at)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (user_id, role_id) DO NOTHING
|
||||
`, userID, roleID, grantedBy, now)
|
||||
userRole := &UserRole{
|
||||
UserID: userID,
|
||||
RoleID: roleID,
|
||||
}
|
||||
_, err := tx.NewInsert().
|
||||
Model(userRole).
|
||||
On("CONFLICT (user_id, role_id) DO NOTHING").
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "tx.ExecContext")
|
||||
return errors.Wrap(err, "tx.NewInsert")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -77,13 +48,13 @@ func RevokeRole(ctx context.Context, tx bun.Tx, userID, roleID int) error {
|
||||
return errors.New("roleID must be positive")
|
||||
}
|
||||
|
||||
// TODO: use proper m2m table instead of raw sql
|
||||
_, err := tx.ExecContext(ctx, `
|
||||
DELETE FROM user_roles
|
||||
WHERE user_id = $1 AND role_id = $2
|
||||
`, userID, roleID)
|
||||
_, err := tx.NewDelete().
|
||||
Model((*UserRole)(nil)).
|
||||
Where("user_id = ?", userID).
|
||||
Where("role_id = ?", roleID).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "tx.ExecContext")
|
||||
return errors.Wrap(err, "tx.NewDelete")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -97,18 +68,19 @@ func HasRole(ctx context.Context, tx bun.Tx, userID int, roleName roles.Role) (b
|
||||
if roleName == "" {
|
||||
return false, errors.New("roleName cannot be empty")
|
||||
}
|
||||
|
||||
// TODO: use proper m2m table instead of TableExpr and Join?
|
||||
count, err := tx.NewSelect().
|
||||
TableExpr("user_roles AS ur").
|
||||
Join("JOIN roles AS r ON r.id = ur.role_id").
|
||||
Where("ur.user_id = ?", userID).
|
||||
Where("r.name = ?", roleName).
|
||||
Where("ur.expires_at IS NULL OR ur.expires_at > ?", time.Now().Unix()).
|
||||
Count(ctx)
|
||||
user := new(User)
|
||||
err := tx.NewSelect().
|
||||
Model(user).
|
||||
Relation("Roles").
|
||||
Where("u.id = ? ", userID).
|
||||
Scan(ctx)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "tx.NewSelect")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
for _, role := range user.Roles {
|
||||
if role.Name == roleName {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user