diff --git a/README.md b/README.md
index 36f7880..6072a12 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
-
+
### Running tests
```bash
cd test/
-go test -bench
+go test
```
\ No newline at end of file
diff --git a/api/log.go b/api/log.go
index 5761420..eee808f 100644
--- a/api/log.go
+++ b/api/log.go
@@ -30,6 +30,11 @@ type GetLogResponse struct {
Logs *[]storage.LogEntry `json:"logs"`
}
+type LogResponse struct {
+ Ok bool `json:"ok"`
+ Message string `json:"message"`
+}
+
func (e *LogRequest) Time() time.Time {
t := time.Unix(e.TimeStamp, 0)
@@ -89,7 +94,7 @@ func (api *WebAPI) LogTrace(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
- r.Json(GetLogResponse{
+ r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
@@ -106,7 +111,7 @@ func (api *WebAPI) LogInfo(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
- r.Json(GetLogResponse{
+ r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
@@ -123,7 +128,7 @@ func (api *WebAPI) LogWarn(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
- r.Json(GetLogResponse{
+ r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
@@ -140,7 +145,7 @@ func (api *WebAPI) LogError(r *Request) {
entry, err := api.parseLogEntry(r)
if err != nil {
- r.Json(GetLogResponse{
+ r.Json(LogResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
diff --git a/api/project.go b/api/project.go
index 1294603..0f561ba 100644
--- a/api/project.go
+++ b/api/project.go
@@ -202,7 +202,15 @@ func (api *WebAPI) ProjectGet(r *Request) {
func (api *WebAPI) ProjectGetAllProjects(r *Request) {
- projects := api.Database.GetAllProjects()
+ worker, _ := api.validateSignature(r)
+
+ var id int64
+ if worker == nil {
+ id = 0
+ } else {
+ id = worker.Id
+ }
+ projects := api.Database.GetAllProjects(id)
r.OkJson(GetAllProjectsResponse{
Ok: true,
diff --git a/api/task.go b/api/task.go
index 7588a7b..d5bb5b0 100644
--- a/api/task.go
+++ b/api/task.go
@@ -156,11 +156,20 @@ func (api *WebAPI) TaskGet(r *Request) {
}
task := api.Database.GetTask(worker)
+ if task == nil {
- r.OkJson(GetTaskResponse{
- Ok: true,
- Task: task,
- })
+ r.OkJson(GetTaskResponse{
+ Ok: false,
+ Message: "No task available",
+ })
+
+ } else {
+
+ r.OkJson(GetTaskResponse{
+ Ok: true,
+ Task: task,
+ })
+ }
}
func (api WebAPI) validateSignature(r *Request) (*storage.Worker, error) {
diff --git a/config.yml b/config.yml
index 3d86868..56629c3 100755
--- a/config.yml
+++ b/config.yml
@@ -8,9 +8,9 @@ database:
git:
webhook_secret: "very_secret_secret"
# Github: sha1, Gogs: sha256
- webhook_hash: "sha1"
+ webhook_hash: "sha256"
# Github: 'X-Hub-Signature', Gogs: 'X-Gogs-Signature'
- webhook_sig_header: "X-Hub-Signature"
+ webhook_sig_header: "X-Gogs-Signature"
log:
# panic, fatal, error, warn, info, debug, trace
diff --git a/schema.sql b/schema.sql
index 67b124b..85cf48b 100755
--- a/schema.sql
+++ b/schema.sql
@@ -113,3 +113,36 @@ CREATE TRIGGER on_task_delete
ON task
FOR EACH ROW
EXECUTE PROCEDURE on_task_delete_proc();
+
+CREATE OR REPLACE FUNCTION release_task_ok(wid INT, tid INT, ver INT) RETURNS BOOLEAN AS
+$$
+DECLARE
+ res INT = NULL;
+BEGIN
+ DELETE FROM task WHERE id = tid AND assignee = wid AND verification_count < 2 RETURNING project INTO res;
+
+ IF res IS NULL THEN
+ INSERT INTO worker_verifies_task (worker, verification_hash, task)
+ SELECT wid, ver, task.id
+ FROM task
+ WHERE assignee = wid;
+
+ DELETE
+ FROM task
+ WHERE id = tid
+ AND assignee = wid
+ AND (SELECT COUNT(*) as vcnt
+ FROM worker_verifies_task wvt
+ WHERE task = tid
+ GROUP BY wvt.verification_hash
+ ORDER BY vcnt DESC
+ LIMIT 1) >= task.verification_count RETURNING task.id INTO res;
+
+ IF res IS NULL THEN
+ UPDATE task SET assignee= NULL WHERE id = tid AND assignee = wid;
+ end if;
+ end if;
+
+ RETURN res IS NOT NULL;
+END;
+$$ LANGUAGE 'plpgsql';
diff --git a/storage/auth.go b/storage/auth.go
index 2613415..b8ebcdd 100644
--- a/storage/auth.go
+++ b/storage/auth.go
@@ -104,8 +104,8 @@ func (database *Database) UpdateManager(manager *Manager) {
func (database *Database) UpdateManagerPassword(manager *Manager, newPassword []byte) {
hash := crypto.SHA512.New()
- hash.Write([]byte(manager.Username))
hash.Write(newPassword)
+ hash.Write([]byte(manager.Username))
hashedPassword := hash.Sum(nil)
db := database.getDB()
diff --git a/storage/project.go b/storage/project.go
index 42299cb..caf1f25 100644
--- a/storage/project.go
+++ b/storage/project.go
@@ -131,14 +131,27 @@ func (database *Database) UpdateProject(project *Project) error {
return nil
}
-func (database Database) GetAllProjects() *[]Project {
+func (database Database) GetAllProjects(workerId int64) *[]Project {
projects := make([]Project, 0)
db := database.getDB()
- rows, err := db.Query(`SELECT
+ var rows *sql.Rows
+ var err error
+ if workerId == 0 {
+ rows, err = db.Query(`SELECT
Id, priority, name, clone_url, git_repo, version, motd, public
FROM project
+ LEFT JOIN worker_has_access_to_project whatp ON whatp.project = id
+ WHERE public
ORDER BY name`)
+ } else {
+ rows, err = db.Query(`SELECT
+ Id, priority, name, clone_url, git_repo, version, motd, public
+ FROM project
+ LEFT JOIN worker_has_access_to_project whatp ON whatp.project = id
+ WHERE public OR whatp.worker = $1
+ ORDER BY name`, workerId)
+ }
handleErr(err)
for rows.Next() {
diff --git a/storage/task.go b/storage/task.go
index 29f66e3..eaf75aa 100644
--- a/storage/task.go
+++ b/storage/task.go
@@ -134,52 +134,34 @@ func (database Database) ReleaseTask(id int64, workerId int64, result TaskResult
db := database.getDB()
- var rowsAffected int64
+ var taskUpdated bool
if result == TR_OK {
- var pid int64
-
- //If no verification is required
- row := db.QueryRow(`DELETE FROM task WHERE id=$1 AND assignee=$2 AND verification_count < 2
- RETURNING project`, id, workerId)
- err := row.Scan(&pid)
- if err == nil {
- rowsAffected = 1
- } else {
- //If verification is required
- _, err = db.Exec(`INSERT INTO worker_verifies_task (worker, verification_hash, task)
- SELECT $1,$2,task.id FROM task WHERE assignee=$1`, workerId, verification)
- handleErr(err)
-
- res, _ := db.Exec(`DELETE FROM task WHERE id=$1 AND assignee=$2 AND
- (SELECT COUNT(*) as vcnt FROM worker_verifies_task wvt WHERE task=$1
- GROUP BY wvt.verification_hash ORDER BY vcnt DESC LIMIT 1) >= task.verification_count`,
- id, workerId)
- rowsAffected, _ = res.RowsAffected()
-
- _, _ = db.Exec(`UPDATE task SET assignee=NULL WHERE id=$1 AND assignee=$2`, id, workerId)
- }
+ row := db.QueryRow(`SELECT release_task_ok($1,$2,$3)`, workerId, id, verification)
+ _ = row.Scan(&taskUpdated)
} else if result == TR_FAIL {
res, err := db.Exec(`UPDATE task SET (status, assignee, retries) =
(CASE WHEN retries+1 >= max_retries THEN 2 ELSE 1 END, NULL, retries+1)
WHERE id=$1 AND assignee=$2`, id, workerId)
handleErr(err)
- rowsAffected, _ = res.RowsAffected()
+ rowsAffected, _ := res.RowsAffected()
+ taskUpdated = rowsAffected == 1
} else if result == TR_SKIP {
res, err := db.Exec(`UPDATE task SET (status, assignee) = (1, NULL)
WHERE id=$1 AND assignee=$2`, id, workerId)
handleErr(err)
- rowsAffected, _ = res.RowsAffected()
+ rowsAffected, _ := res.RowsAffected()
+ taskUpdated = rowsAffected == 1
}
logrus.WithFields(logrus.Fields{
- "rowsAffected": rowsAffected,
+ "taskUpdated": taskUpdated,
"taskId": id,
"workerId": workerId,
"verification": verification,
}).Trace("Database.ReleaseTask")
- return rowsAffected == 1
+ return taskUpdated
}
func (database *Database) GetTaskFromProject(worker *Worker, projectId int64) *Task {
diff --git a/test/schema.sql b/test/schema.sql
index 67b124b..85cf48b 100755
--- a/test/schema.sql
+++ b/test/schema.sql
@@ -113,3 +113,36 @@ CREATE TRIGGER on_task_delete
ON task
FOR EACH ROW
EXECUTE PROCEDURE on_task_delete_proc();
+
+CREATE OR REPLACE FUNCTION release_task_ok(wid INT, tid INT, ver INT) RETURNS BOOLEAN AS
+$$
+DECLARE
+ res INT = NULL;
+BEGIN
+ DELETE FROM task WHERE id = tid AND assignee = wid AND verification_count < 2 RETURNING project INTO res;
+
+ IF res IS NULL THEN
+ INSERT INTO worker_verifies_task (worker, verification_hash, task)
+ SELECT wid, ver, task.id
+ FROM task
+ WHERE assignee = wid;
+
+ DELETE
+ FROM task
+ WHERE id = tid
+ AND assignee = wid
+ AND (SELECT COUNT(*) as vcnt
+ FROM worker_verifies_task wvt
+ WHERE task = tid
+ GROUP BY wvt.verification_hash
+ ORDER BY vcnt DESC
+ LIMIT 1) >= task.verification_count RETURNING task.id INTO res;
+
+ IF res IS NULL THEN
+ UPDATE task SET assignee= NULL WHERE id = tid AND assignee = wid;
+ end if;
+ end if;
+
+ RETURN res IS NOT NULL;
+END;
+$$ LANGUAGE 'plpgsql';
diff --git a/updateBadges.sh b/updateBadges.sh
deleted file mode 100755
index 368678b..0000000
--- a/updateBadges.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-
-gopherbadger -md="README.md" -png=false -style flat-square
-rm coverage.out
\ No newline at end of file
diff --git a/web/angular/src/app/create-project/create-project.component.html b/web/angular/src/app/create-project/create-project.component.html
index dbeb4ef..1757192 100644
--- a/web/angular/src/app/create-project/create-project.component.html
+++ b/web/angular/src/app/create-project/create-project.component.html
@@ -4,35 +4,31 @@
{{"project.create_subtitle" | translate}}
-
-
+
diff --git a/web/angular/src/app/project-dashboard/project-dashboard.component.ts b/web/angular/src/app/project-dashboard/project-dashboard.component.ts
index 7dda45f..ef8673f 100644
--- a/web/angular/src/app/project-dashboard/project-dashboard.component.ts
+++ b/web/angular/src/app/project-dashboard/project-dashboard.component.ts
@@ -71,7 +71,7 @@ export class ProjectDashboardComponent implements OnInit {
}
this.noTasks = false;
- this.timeline.data.labels = this.snapshots.map(s => s.time_stamp as any);
+ this.timeline.data.labels = this.snapshots.map(s => s.time_stamp * 1000 as any);
this.timeline.data.datasets = this.makeTimelineDataset(this.snapshots);
this.timeline.update();
this.statusPie.data.datasets = [
@@ -164,7 +164,7 @@ export class ProjectDashboardComponent implements OnInit {
this.timeline = new Chart(ctx, {
type: "bar",
data: {
- labels: this.snapshots.map(s => s.time_stamp as any),
+ labels: this.snapshots.map(s => s.time_stamp * 1000 as any),
datasets: this.makeTimelineDataset(this.snapshots),
},
options: {
@@ -198,11 +198,16 @@ export class ProjectDashboardComponent implements OnInit {
private setupStatusPie() {
- if (this.lastSnapshot == null || (this.lastSnapshot.awaiting_verification_count == 0 &&
+ if (this.lastSnapshot == undefined || (this.lastSnapshot.awaiting_verification_count == 0 &&
this.lastSnapshot.closed_task_count == 0 &&
this.lastSnapshot.new_task_count == 0 &&
this.lastSnapshot.failed_task_count == 0)) {
this.noTasks = true;
+
+ this.lastSnapshot = {
+ closed_task_count: 0, time_stamp: 0, failed_task_count: 0,
+ new_task_count: 0, awaiting_verification_count: 0
+ }
}
let elem = document.getElementById("status-pie") as any;