Files
foundry-core/internal/platform/grants.go
T
codex-bot bfcea1b3af
Foundry Go checks / check (push) Successful in 1m51s
Foundry Go checks / check (pull_request) Successful in 1m56s
Add structured materials, canvas layouts, tags and content permissions
2026-11-05 18:36:53 +08:00

97 lines
2.7 KiB
Go

package platform
import "net/http"
func (s *service) materialGrants(w http.ResponseWriter, r *http.Request, project, account string) error {
workspace, material := r.PathValue("workspace"), r.PathValue("material")
if r.Method != http.MethodGet && r.Method != http.MethodPost {
reject(w, 405, "method_not_allowed")
return nil
}
tx, err := s.db.BeginTx(r.Context(), nil)
if err != nil {
return err
}
defer tx.Rollback()
_, role, err := lockMaterial(r.Context(), tx, project, workspace, material, account)
if err != nil {
return err
}
if role != "admin" {
reject(w, 403, "admin_required")
return nil
}
if r.Method == http.MethodGet {
rows, err := tx.QueryContext(r.Context(), "SELECT account_id::text,role FROM material_grants WHERE project=$1 AND workspace_id=$2 AND material_id=$3 ORDER BY account_id LIMIT 1000", project, workspace, material)
if err != nil {
return err
}
defer rows.Close()
items := []response{}
for rows.Next() {
var id, role string
if err := rows.Scan(&id, &role); err != nil {
return err
}
items = append(items, response{"account_id": id, "role": role})
}
if err := rows.Err(); err != nil {
return err
}
reply(w, 200, response{"items": items})
return nil
}
var input struct {
AccountID string `json:"account_id"`
Role string `json:"role"`
}
if !decode(w, r, &input) {
return nil
}
if input.Role != "editor" && input.Role != "viewer" {
reject(w, 400, "invalid_role")
return nil
}
_, err = tx.ExecContext(r.Context(), `
INSERT INTO material_grants(project,workspace_id,material_id,account_id,role) VALUES($1,$2,$3,$4,$5)
ON CONFLICT(project,workspace_id,material_id,account_id) DO UPDATE SET role=EXCLUDED.role
`, project, workspace, material, input.AccountID, input.Role)
if err != nil {
return err
}
if err = tx.Commit(); err != nil {
return err
}
reply(w, 204, nil)
return nil
}
func (s *service) deleteMaterialGrant(w http.ResponseWriter, r *http.Request, project, account string) error {
if r.Method != http.MethodDelete {
reject(w, 405, "method_not_allowed")
return nil
}
workspace, material := r.PathValue("workspace"), r.PathValue("material")
tx, err := s.db.BeginTx(r.Context(), nil)
if err != nil {
return err
}
defer tx.Rollback()
_, role, err := lockMaterial(r.Context(), tx, project, workspace, material, account)
if err != nil {
return err
}
if role != "admin" {
reject(w, 403, "admin_required")
return nil
}
_, err = tx.ExecContext(r.Context(), "DELETE FROM material_grants WHERE project=$1 AND workspace_id=$2 AND material_id=$3 AND account_id=$4", project, workspace, material, r.PathValue("account"))
if err != nil {
return err
}
if err = tx.Commit(); err != nil {
return err
}
reply(w, 204, nil)
return nil
}