mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-11 14:08:52 +00:00
Some work on permissions (lacks tests)
This commit is contained in:
@@ -10,9 +10,10 @@ import (
|
||||
type ManagerRole int
|
||||
|
||||
const (
|
||||
ROLE_NONE ManagerRole = 0
|
||||
ROLE_READ ManagerRole = 1
|
||||
ROLE_EDIT ManagerRole = 2
|
||||
ROLE_MANAGE_ACCESS ManagerRole = 3
|
||||
ROLE_MANAGE_ACCESS ManagerRole = 4
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
@@ -65,8 +66,8 @@ func (database *Database) SaveManager(manager *Manager, password []byte) error {
|
||||
hash.Write([]byte(manager.Username))
|
||||
hashedPassword := hash.Sum(nil)
|
||||
|
||||
row := db.QueryRow(`INSERT INTO manager (username, password, website_admin)
|
||||
VALUES ($1,$2,$3) RETURNING ID`,
|
||||
row := db.QueryRow(`INSERT INTO manager (username, password, website_admin, register_time)
|
||||
VALUES ($1,$2,$3, extract(epoch from now() at time zone 'utc')) RETURNING ID`,
|
||||
manager.Username, hashedPassword, manager.WebsiteAdmin)
|
||||
|
||||
err := row.Scan(&manager.Id)
|
||||
@@ -78,6 +79,8 @@ func (database *Database) SaveManager(manager *Manager, password []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
manager.WebsiteAdmin = manager.Id == 1
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"manager": manager,
|
||||
}).Info("Database.SaveManager INSERT")
|
||||
@@ -121,3 +124,19 @@ func (database *Database) UpdateManagerPassword(manager *Manager, newPassword []
|
||||
"id": manager.Id,
|
||||
}).Warning("Database.UpdateManagerPassword UPDATE")
|
||||
}
|
||||
|
||||
func (database *Database) ManagerHasRoleOn(manager *Manager, projectId int64) ManagerRole {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
row := db.QueryRow(`SELECT role FROM manager_has_role_on_project
|
||||
WHERE project=$1 AND manager=$2`, projectId, manager.Id)
|
||||
|
||||
var role ManagerRole
|
||||
err := row.Scan(&role)
|
||||
if err != nil {
|
||||
return ROLE_NONE
|
||||
}
|
||||
|
||||
return role
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func (database *Database) MakeProjectSnapshots() {
|
||||
"took": time.Now().Sub(startTime),
|
||||
"add": inserted,
|
||||
"remove": deleted,
|
||||
}).Trace("Took monitoring snapshot")
|
||||
}).Trace("Took project monitoring snapshot")
|
||||
}
|
||||
|
||||
func (database *Database) GetMonitoringSnapshotsBetween(pid int64, from int, to int) (ss *[]ProjectMonitoringSnapshot) {
|
||||
|
||||
@@ -15,6 +15,7 @@ type Project struct {
|
||||
Version string `json:"version"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
}
|
||||
|
||||
type AssignedTasks struct {
|
||||
@@ -31,9 +32,10 @@ func (database *Database) SaveProject(project *Project) (int64, error) {
|
||||
|
||||
func saveProject(project *Project, db *sql.DB) (int64, error) {
|
||||
|
||||
row := db.QueryRow(`INSERT INTO project (name, git_repo, clone_url, version, priority, motd, public)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7) RETURNING id`,
|
||||
project.Name, project.GitRepo, project.CloneUrl, project.Version, project.Priority, project.Motd, project.Public)
|
||||
row := db.QueryRow(`INSERT INTO project (name, git_repo, clone_url, version, priority, motd, public, hidden)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING id`,
|
||||
project.Name, project.GitRepo, project.CloneUrl, project.Version, project.Priority, project.Motd,
|
||||
project.Public, project.Hidden)
|
||||
|
||||
var id int64
|
||||
err := row.Scan(&id)
|
||||
@@ -64,7 +66,7 @@ func (database *Database) GetProject(id int64) *Project {
|
||||
|
||||
func getProject(id int64, db *sql.DB) *Project {
|
||||
|
||||
row := db.QueryRow(`SELECT id, priority, name, clone_url, git_repo, version, motd, public
|
||||
row := db.QueryRow(`SELECT id, priority, name, clone_url, git_repo, version, motd, public, hidden
|
||||
FROM project WHERE id=$1`, id)
|
||||
|
||||
project, err := scanProject(row)
|
||||
@@ -87,7 +89,7 @@ func scanProject(row *sql.Row) (*Project, error) {
|
||||
|
||||
project := &Project{}
|
||||
err := row.Scan(&project.Id, &project.Priority, &project.Name, &project.CloneUrl,
|
||||
&project.GitRepo, &project.Version, &project.Motd, &project.Public)
|
||||
&project.GitRepo, &project.Version, &project.Motd, &project.Public, &project.Hidden)
|
||||
|
||||
return project, err
|
||||
}
|
||||
@@ -95,7 +97,7 @@ func scanProject(row *sql.Row) (*Project, error) {
|
||||
func (database *Database) GetProjectWithRepoName(repoName string) *Project {
|
||||
|
||||
db := database.getDB()
|
||||
row := db.QueryRow(`SELECT id, priority, name, clone_url, git_repo, version, motd, public
|
||||
row := db.QueryRow(`SELECT id, priority, name, clone_url, git_repo, version, motd, public, hidden
|
||||
FROM project WHERE LOWER(git_repo)=$1`,
|
||||
strings.ToLower(repoName))
|
||||
|
||||
@@ -115,8 +117,9 @@ func (database *Database) UpdateProject(project *Project) error {
|
||||
db := database.getDB()
|
||||
|
||||
res, err := db.Exec(`UPDATE project
|
||||
SET (priority, name, clone_url, git_repo, version, motd, public) = ($1,$2,$3,$4,$5,$6,$7) WHERE id=$8`,
|
||||
project.Priority, project.Name, project.CloneUrl, project.GitRepo, project.Version, project.Motd, project.Public, project.Id)
|
||||
SET (priority, name, clone_url, git_repo, version, motd, public, hidden) = ($1,$2,$3,$4,$5,$6,$7,$8) WHERE id=$9`,
|
||||
project.Priority, project.Name, project.CloneUrl, project.GitRepo, project.Version, project.Motd,
|
||||
project.Public, project.Hidden, project.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -139,26 +142,24 @@ func (database Database) GetAllProjects(workerId int64) *[]Project {
|
||||
var err error
|
||||
if workerId == 0 {
|
||||
rows, err = db.Query(`SELECT
|
||||
Id, priority, name, clone_url, git_repo, version, motd, public
|
||||
Id, priority, name, clone_url, git_repo, version, motd, public, hidden
|
||||
FROM project
|
||||
LEFT JOIN worker_has_access_to_project whatp ON whatp.project = id
|
||||
WHERE public
|
||||
WHERE NOT hidden
|
||||
ORDER BY name`)
|
||||
} else {
|
||||
rows, err = db.Query(`SELECT
|
||||
Id, priority, name, clone_url, git_repo, version, motd, public
|
||||
Id, priority, name, clone_url, git_repo, version, motd, public, hidden
|
||||
FROM project
|
||||
LEFT JOIN worker_has_access_to_project whatp ON whatp.project = id
|
||||
WHERE public OR whatp.worker = $1
|
||||
WHERE NOT hidden OR whatp.worker = $1
|
||||
ORDER BY name`, workerId)
|
||||
}
|
||||
handleErr(err)
|
||||
|
||||
for rows.Next() {
|
||||
|
||||
p := Project{}
|
||||
err := rows.Scan(&p.Id, &p.Priority, &p.Name, &p.CloneUrl,
|
||||
&p.GitRepo, &p.Version, &p.Motd, &p.Public)
|
||||
&p.GitRepo, &p.Version, &p.Motd, &p.Public, &p.Hidden)
|
||||
handleErr(err)
|
||||
projects = append(projects, p)
|
||||
}
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Identity struct {
|
||||
RemoteAddr string `json:"remote_addr"`
|
||||
UserAgent string `json:"user_agent"`
|
||||
}
|
||||
|
||||
type Worker struct {
|
||||
Id int64 `json:"id"`
|
||||
Created int64 `json:"created"`
|
||||
Identity *Identity `json:"identity"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Secret []byte `json:"secret"`
|
||||
Id int64 `json:"id"`
|
||||
Created int64 `json:"created"`
|
||||
Alias string `json:"alias,omitempty"`
|
||||
Secret []byte `json:"secret"`
|
||||
}
|
||||
|
||||
type WorkerStats struct {
|
||||
@@ -28,10 +20,8 @@ func (database *Database) SaveWorker(worker *Worker) {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
identityId := getOrCreateIdentity(worker.Identity, db)
|
||||
|
||||
row := db.QueryRow("INSERT INTO worker (created, identity, secret, alias) VALUES ($1,$2,$3,$4) RETURNING id",
|
||||
worker.Created, identityId, worker.Secret, worker.Alias)
|
||||
row := db.QueryRow("INSERT INTO worker (created, secret, alias) VALUES ($1,$2,$3) RETURNING id",
|
||||
worker.Created, worker.Secret, worker.Alias)
|
||||
|
||||
err := row.Scan(&worker.Id)
|
||||
handleErr(err)
|
||||
@@ -46,10 +36,9 @@ func (database *Database) GetWorker(id int64) *Worker {
|
||||
db := database.getDB()
|
||||
|
||||
worker := &Worker{}
|
||||
var identityId int64
|
||||
|
||||
row := db.QueryRow("SELECT id, created, identity, secret, alias FROM worker WHERE id=$1", id)
|
||||
err := row.Scan(&worker.Id, &worker.Created, &identityId, &worker.Secret, &worker.Alias)
|
||||
row := db.QueryRow("SELECT id, created, secret, alias FROM worker WHERE id=$1", id)
|
||||
err := row.Scan(&worker.Id, &worker.Created, &worker.Secret, &worker.Alias)
|
||||
if err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"id": id,
|
||||
@@ -57,9 +46,6 @@ func (database *Database) GetWorker(id int64) *Worker {
|
||||
return nil
|
||||
}
|
||||
|
||||
worker.Identity, err = getIdentity(identityId, db)
|
||||
handleErr(err)
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"worker": worker,
|
||||
}).Trace("Database.getWorker SELECT worker")
|
||||
@@ -67,48 +53,6 @@ func (database *Database) GetWorker(id int64) *Worker {
|
||||
return worker
|
||||
}
|
||||
|
||||
func getIdentity(id int64, db *sql.DB) (*Identity, error) {
|
||||
|
||||
identity := &Identity{}
|
||||
|
||||
row := db.QueryRow("SELECT remote_addr, user_agent FROM worker_identity WHERE id=$1", id)
|
||||
err := row.Scan(&identity.RemoteAddr, &identity.UserAgent)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.New("identity not found")
|
||||
}
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"identity": identity,
|
||||
}).Trace("Database.getIdentity SELECT workerIdentity")
|
||||
|
||||
return identity, nil
|
||||
}
|
||||
|
||||
func getOrCreateIdentity(identity *Identity, db *sql.DB) int64 {
|
||||
|
||||
res, err := db.Exec("INSERT INTO worker_identity (remote_addr, user_agent) VALUES ($1,$2) ON CONFLICT DO NOTHING",
|
||||
identity.RemoteAddr, identity.UserAgent)
|
||||
handleErr(err)
|
||||
|
||||
rowsAffected, err := res.RowsAffected()
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"rowsAffected": rowsAffected,
|
||||
}).Trace("Database.saveWorker INSERT workerIdentity")
|
||||
|
||||
row := db.QueryRow("SELECT (id) FROM worker_identity WHERE remote_addr=$1", identity.RemoteAddr)
|
||||
|
||||
var rowId int64
|
||||
err = row.Scan(&rowId)
|
||||
handleErr(err)
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"rowId": rowId,
|
||||
}).Trace("Database.saveWorker SELECT workerIdentity")
|
||||
|
||||
return rowId
|
||||
}
|
||||
|
||||
func (database *Database) GrantAccess(workerId int64, projectId int64) bool {
|
||||
|
||||
db := database.getDB()
|
||||
@@ -169,6 +113,88 @@ func (database *Database) UpdateWorker(worker *Worker) bool {
|
||||
return rowsAffected == 1
|
||||
}
|
||||
|
||||
func (database *Database) SaveAccessRequest(worker *Worker, projectId int64) bool {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
res, err := db.Exec(`INSERT INTO worker_requests_access_to_project
|
||||
SELECT $1, id FROM project WHERE id=$2 AND NOT project.public
|
||||
AND NOT EXISTS(SELECT * FROM worker_has_access_to_project WHERE worker=$1 AND project=$2)`,
|
||||
worker.Id, projectId)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
rowsAffected, _ := res.RowsAffected()
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"rowsAffected": rowsAffected,
|
||||
}).Trace("Database.SaveAccessRequest INSERT")
|
||||
|
||||
return rowsAffected == 1
|
||||
}
|
||||
|
||||
func (database *Database) AcceptAccessRequest(worker *Worker, projectId int64) bool {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
res, err := db.Exec(`DELETE FROM worker_requests_access_to_project
|
||||
WHERE worker=$1 AND project=$2`)
|
||||
handleErr(err)
|
||||
|
||||
rowsAffected, _ := res.RowsAffected()
|
||||
if rowsAffected == 1 {
|
||||
_, err := db.Exec(`INSERT INTO worker_has_access_to_project
|
||||
(worker, project) VALUES ($1,$2)`,
|
||||
worker.Id, projectId)
|
||||
handleErr(err)
|
||||
}
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"rowsAffected": rowsAffected,
|
||||
}).Trace("Database.AcceptAccessRequest")
|
||||
|
||||
return rowsAffected == 1
|
||||
}
|
||||
|
||||
func (database *Database) RejectAccessRequest(worker *Worker, projectId int64) bool {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
res, err := db.Exec(`DELETE FROM worker_requests_access_to_project
|
||||
WHERE worker=$1 AND project=$2`, worker.Id, projectId)
|
||||
handleErr(err)
|
||||
|
||||
rowsAffected, _ := res.RowsAffected()
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"rowsAffected": rowsAffected,
|
||||
}).Trace("Database.AcceptAccessRequest")
|
||||
|
||||
return rowsAffected == 1
|
||||
}
|
||||
|
||||
func (database *Database) GetAllAccessRequests(projectId int64) *[]Worker {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
rows, err := db.Query(`SELECT id, alias, created FROM worker_requests_access_to_project
|
||||
INNER JOIN worker w on worker_requests_access_to_project.worker = w.id
|
||||
WHERE project=$1`,
|
||||
projectId)
|
||||
handleErr(err)
|
||||
|
||||
requests := make([]Worker, 0)
|
||||
|
||||
for rows.Next() {
|
||||
w := Worker{}
|
||||
_ = rows.Scan(&w.Id, &w.Alias, &w.Created)
|
||||
requests = append(requests, w)
|
||||
}
|
||||
|
||||
return &requests
|
||||
}
|
||||
|
||||
func (database *Database) GetAllWorkerStats() *[]WorkerStats {
|
||||
|
||||
db := database.getDB()
|
||||
|
||||
Reference in New Issue
Block a user