diff --git a/api/git.go b/api/git.go index cd7a379..db8da4e 100644 --- a/api/git.go +++ b/api/git.go @@ -16,13 +16,6 @@ import ( func (api *WebAPI) ReceiveGitWebHook(r *Request) { - if !signatureValid(r) { - logrus.Error("WebHook signature does not match!") - r.Ctx.SetStatusCode(403) - _, _ = fmt.Fprintf(r.Ctx, "Signature does not match") - return - } - payload := &GitPayload{} err := json.Unmarshal(r.Ctx.Request.Body(), payload) if err != nil { @@ -35,11 +28,27 @@ func (api *WebAPI) ReceiveGitWebHook(r *Request) { }).Info("Received git WebHook") if !isProductionBranch(payload) { + r.Ctx.SetStatusCode(400) return } project := api.getAssociatedProject(payload) if project == nil { + r.Ctx.SetStatusCode(400) + return + } + + signature, err := api.Database.GetWebhookSecret(project.Id) + if err != nil { + _, _ = fmt.Fprintf(r.Ctx, err.Error()) + r.Ctx.SetStatusCode(400) + return + } + + if !signatureValid(r, signature) { + logrus.Error("WebHook signature does not match!") + r.Ctx.SetStatusCode(403) + _, _ = fmt.Fprintf(r.Ctx, "Signature does not match") return } @@ -50,7 +59,7 @@ func (api *WebAPI) ReceiveGitWebHook(r *Request) { handleErr(err, r) } -func signatureValid(r *Request) (matches bool) { +func signatureValid(r *Request, webhookSignature string) (matches bool) { signature := parseSignatureFromRequest(r.Ctx) @@ -60,7 +69,7 @@ func signatureValid(r *Request) (matches bool) { body := r.Ctx.PostBody() - mac := hmac.New(getHashFuncFromConfig(), config.Cfg.WebHookSecret) + mac := hmac.New(getHashFuncFromConfig(), []byte(webhookSignature)) mac.Write(body) expectedMac := hex.EncodeToString(mac.Sum(nil)) diff --git a/api/main.go b/api/main.go index d5b3ff8..3008e46 100644 --- a/api/main.go +++ b/api/main.go @@ -93,6 +93,8 @@ func New() *WebAPI { api.router.POST("/project/reject_request/:id/:wid", LogRequestMiddleware(api.RejectAccessRequest)) api.router.GET("/project/secret/:id", LogRequestMiddleware(api.GetSecret)) api.router.POST("/project/secret/:id", LogRequestMiddleware(api.SetSecret)) + api.router.GET("/project/webhook_secret/:id", LogRequestMiddleware(api.GetWebhookSecret)) + api.router.POST("/project/webhook_secret/:id", LogRequestMiddleware(api.SetWebhookSecret)) api.router.POST("/task/submit", LogRequestMiddleware(api.SubmitTask)) api.router.GET("/task/get/:project", LogRequestMiddleware(api.GetTaskFromProject)) diff --git a/api/models.go b/api/models.go index d86bb9b..c4f8b23 100644 --- a/api/models.go +++ b/api/models.go @@ -292,3 +292,10 @@ type SetSecretRequest struct { type GetSecretResponse struct { Secret string `json:"secret"` } + +type SetWebhookSecretRequest struct { + WebhookSecret string `json:"webhook_secret"` +} +type GetWebhookSecretResponse struct { + WebhookSecret string `json:"webhook_secret"` +} diff --git a/api/project.go b/api/project.go index 56ef278..1b9552a 100644 --- a/api/project.go +++ b/api/project.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "github.com/Sirupsen/logrus" + "github.com/google/uuid" "github.com/simon987/task_tracker/storage" "strconv" ) @@ -97,7 +98,9 @@ func (api *WebAPI) CreateProject(r *Request) { return } - id, err := api.Database.SaveProject(project) + webhookSecret := makeWebhookSecret() + + id, err := api.Database.SaveProject(project, webhookSecret) if err != nil { r.Json(JsonResponse{ Ok: false, @@ -107,7 +110,7 @@ func (api *WebAPI) CreateProject(r *Request) { } api.Database.SetManagerRoleOn(manager.(*storage.Manager).Id, id, - storage.ROLE_MANAGE_ACCESS|storage.ROLE_READ|storage.ROLE_EDIT) + storage.RoleManageAccess|storage.RoleRead|storage.RoleEdit|storage.RoleSecret) r.OkJson(JsonResponse{ Ok: true, Content: CreateProjectResponse{ @@ -119,6 +122,10 @@ func (api *WebAPI) CreateProject(r *Request) { }).Debug("Created project") } +func makeWebhookSecret() string { + return uuid.New().String() +} + func (api *WebAPI) UpdateProject(r *Request) { id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64) @@ -163,7 +170,7 @@ func (api *WebAPI) UpdateProject(r *Request) { sess := api.Session.StartFasthttp(r.Ctx) manager := sess.Get("manager") - if !isActionOnProjectAuthorized(project.Id, manager, storage.ROLE_EDIT, api.Database) { + if !isActionOnProjectAuthorized(project.Id, manager, storage.RoleEdit, api.Database) { r.Json(JsonResponse{ Ok: false, Message: "Unauthorized", @@ -238,7 +245,7 @@ func isProjectReadAuthorized(project *storage.Project, manager interface{}, db * return true } role := db.GetManagerRoleOn(manager.(*storage.Manager), project.Id) - if role&storage.ROLE_READ == 1 { + if role&storage.RoleRead == 1 { return true } @@ -302,7 +309,7 @@ func (api *WebAPI) GetWorkerAccessListForProject(r *Request) { return } - if !isActionOnProjectAuthorized(id, manager, storage.ROLE_MANAGE_ACCESS, api.Database) { + if !isActionOnProjectAuthorized(id, manager, storage.RoleManageAccess, api.Database) { r.Json(JsonResponse{ Ok: false, Message: "Unauthorized", @@ -391,7 +398,7 @@ func (api *WebAPI) AcceptAccessRequest(r *Request) { sess := api.Session.StartFasthttp(r.Ctx) manager := sess.Get("manager") - if !isActionOnProjectAuthorized(pid, manager, storage.ROLE_MANAGE_ACCESS, api.Database) { + if !isActionOnProjectAuthorized(pid, manager, storage.RoleManageAccess, api.Database) { r.Json(JsonResponse{ Message: "Unauthorized", Ok: false, @@ -471,7 +478,7 @@ func (api *WebAPI) SetManagerRoleOnProject(r *Request) { sess := api.Session.StartFasthttp(r.Ctx) manager := sess.Get("manager") - if !isActionOnProjectAuthorized(pid, manager, storage.ROLE_MANAGE_ACCESS, api.Database) { + if !isActionOnProjectAuthorized(pid, manager, storage.RoleManageAccess, api.Database) { r.Json(JsonResponse{ Message: "Unauthorized", Ok: false, @@ -500,7 +507,7 @@ func (api *WebAPI) SetSecret(r *Request) { sess := api.Session.StartFasthttp(r.Ctx) manager := sess.Get("manager") - if !isActionOnProjectAuthorized(pid, manager, storage.ROLE_EDIT, api.Database) { + if !isActionOnProjectAuthorized(pid, manager, storage.RoleSecret, api.Database) { r.Json(JsonResponse{ Ok: false, Message: "Unauthorized", @@ -560,7 +567,7 @@ func (api *WebAPI) GetSecret(r *Request) { sess := api.Session.StartFasthttp(r.Ctx) manager := sess.Get("manager") - if !isActionOnProjectAuthorized(pid, manager, storage.ROLE_EDIT, api.Database) { + if !isActionOnProjectAuthorized(pid, manager, storage.RoleSecret, api.Database) { r.Json(JsonResponse{ Ok: false, Message: "Unauthorized", @@ -576,3 +583,79 @@ func (api *WebAPI) GetSecret(r *Request) { }, }) } + +func (api *WebAPI) GetWebhookSecret(r *Request) { + + pid, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64) + if err != nil || pid <= 0 { + r.Json(JsonResponse{ + Ok: false, + Message: "Invalid project id", + }, 400) + return + } + + sess := api.Session.StartFasthttp(r.Ctx) + manager := sess.Get("manager") + + if !isActionOnProjectAuthorized(pid, manager, storage.RoleSecret, api.Database) { + r.Json(JsonResponse{ + Ok: false, + Message: "Unauthorized", + }, 403) + return + } + + secret, err := api.Database.GetWebhookSecret(pid) + r.OkJson(JsonResponse{ + Ok: true, + Content: GetWebhookSecretResponse{ + WebhookSecret: secret, + }, + }) +} + +func (api *WebAPI) SetWebhookSecret(r *Request) { + + pid, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64) + if err != nil || pid <= 0 { + r.Json(JsonResponse{ + Ok: false, + Message: "Invalid project id", + }, 400) + return + } + + req := &SetWebhookSecretRequest{} + err = json.Unmarshal(r.Ctx.Request.Body(), req) + if err != nil { + r.Json(JsonResponse{ + Ok: false, + Message: "Could not parse request", + }, 400) + return + } + + sess := api.Session.StartFasthttp(r.Ctx) + manager := sess.Get("manager") + + if !isActionOnProjectAuthorized(pid, manager, storage.RoleSecret, api.Database) { + r.Json(JsonResponse{ + Ok: false, + Message: "Unauthorized", + }, 403) + return + } + + err = api.Database.SetWebhookSecret(pid, req.WebhookSecret) + if err == nil { + r.OkJson(JsonResponse{ + Ok: true, + }) + } else { + r.OkJson(JsonResponse{ + Ok: false, + Message: err.Error(), + }) + } +} diff --git a/config.yml b/config.yml index d24d2d0..30f6512 100755 --- a/config.yml +++ b/config.yml @@ -7,7 +7,6 @@ database: log_levels: ["error", "info", "warn"] git: - webhook_secret: "very_secret_secret" # Github: sha1, Gogs: sha256 webhook_hash: "sha256" # Github: 'X-Hub-Signature', Gogs: 'X-Gogs-Signature' diff --git a/storage/auth.go b/storage/auth.go index d195224..5c69e2f 100644 --- a/storage/auth.go +++ b/storage/auth.go @@ -11,10 +11,11 @@ import ( type ManagerRole int const ( - ROLE_NONE ManagerRole = 0 - ROLE_READ ManagerRole = 1 - ROLE_EDIT ManagerRole = 2 - ROLE_MANAGE_ACCESS ManagerRole = 4 + RoleNone ManagerRole = 0 + RoleRead ManagerRole = 1 + RoleEdit ManagerRole = 2 + RoleManageAccess ManagerRole = 4 + RoleSecret ManagerRole = 8 ) type Manager struct { @@ -142,7 +143,7 @@ func (database *Database) GetManagerRoleOn(manager *Manager, projectId int64) Ma var role ManagerRole err := row.Scan(&role) if err != nil { - return ROLE_NONE + return RoleNone } return role diff --git a/storage/project.go b/storage/project.go index 49f16c3..dba5b8d 100644 --- a/storage/project.go +++ b/storage/project.go @@ -25,14 +25,14 @@ type AssignedTasks struct { TaskCount int64 `json:"task_count"` } -func (database *Database) SaveProject(project *Project) (int64, error) { +func (database *Database) SaveProject(project *Project, webhookSecret string) (int64, error) { db := database.getDB() row := db.QueryRow(`INSERT INTO project (name, git_repo, clone_url, version, priority, - motd, public, hidden, chain, paused) - VALUES ($1,$2,$3,$4,$5,$6,$7,$8,NULLIF($9, 0),$10) RETURNING id`, + motd, public, hidden, chain, paused, webhook_secret) + VALUES ($1,$2,$3,$4,$5,$6,$7,$8,NULLIF($9, 0),$10,$11) RETURNING id`, project.Name, project.GitRepo, project.CloneUrl, project.Version, project.Priority, project.Motd, - project.Public, project.Hidden, project.Chain, project.Paused) + project.Public, project.Hidden, project.Chain, project.Paused, webhookSecret) var id int64 err := row.Scan(&id) @@ -225,3 +225,23 @@ func (database *Database) SetSecret(pid int64, secret string) { "project": pid, }).Info("Set secret") } + +func (database *Database) GetWebhookSecret(pid int64) (secret string, err error) { + db := database.getDB() + row := db.QueryRow(`SELECT webhook_secret FROM project WHERE id=$1`, pid) + err = row.Scan(&secret) + return +} + +func (database *Database) SetWebhookSecret(pid int64, secret string) (err error) { + db := database.getDB() + res, err := db.Exec(`UPDATE project SET webhook_secret=$1 WHERE id=$2`, secret, pid) + handleErr(err) + + rowsAffected, _ := res.RowsAffected() + logrus.WithFields(logrus.Fields{ + "project": pid, + "rowsAffected": rowsAffected, + }).Trace("Update webhook secret") + return +} diff --git a/test/api_auth_test.go b/test/api_auth_test.go index fc371ce..ed1b201 100644 --- a/test/api_auth_test.go +++ b/test/api_auth_test.go @@ -3,6 +3,7 @@ package test import ( "bytes" "encoding/json" + "fmt" "github.com/simon987/task_tracker/api" "github.com/simon987/task_tracker/config" "golang.org/x/net/publicsuffix" @@ -177,3 +178,15 @@ func getSessionCtx(username string, password string, admin bool) *http.Client { return client } + +func setRoleOnProject(req api.SetManagerRoleOnProjectRequest, pid int64, s *http.Client) (ar api.JsonResponse) { + r := Post(fmt.Sprintf("/manager/set_role_for_project/%d", pid), req, nil, s) + UnmarshalResponse(r, &ar) + return +} + +func getAccountDetails(s *http.Client) (ar AccountAR) { + r := Get("/account", nil, s) + UnmarshalResponse(r, &ar) + return +} diff --git a/test/api_git_test.go b/test/api_git_test.go index 8291668..0123e5d 100644 --- a/test/api_git_test.go +++ b/test/api_git_test.go @@ -15,7 +15,7 @@ func TestWebHookNoSignature(t *testing.T) { r := Post("/git/receivehook", api.GitPayload{}, nil, nil) - if r.StatusCode != 403 { + if r.StatusCode == 200 { t.Error() } } @@ -28,7 +28,7 @@ func TestWebHookInvalidSignature(t *testing.T) { client := http.Client{} r, _ := client.Do(req) - if r.StatusCode != 403 { + if r.StatusCode == 200 { t.Error() } } @@ -41,10 +41,12 @@ func TestWebHookDontUpdateVersion(t *testing.T) { GitRepo: "username/not_this_one", }).Content + webhookSecret := getWebhookSecret(resp.Id, testAdminCtx).Content.WebhookSecret + body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`) bodyReader := bytes.NewReader(body) - mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret) + mac := hmac.New(crypto.SHA1.New, []byte(webhookSecret)) mac.Write(body) signature := hex.EncodeToString(mac.Sum(nil)) signature = "sha1=" + signature @@ -53,11 +55,7 @@ func TestWebHookDontUpdateVersion(t *testing.T) { req.Header.Add("X-Hub-Signature", signature) client := http.Client{} - r, _ := client.Do(req) - - if r.StatusCode != 200 { - t.Error() - } + _, _ = client.Do(req) getResp := getProjectAsAdmin(resp.Id).Content @@ -76,7 +74,9 @@ func TestWebHookUpdateVersion(t *testing.T) { body := []byte(`{"ref": "refs/heads/master", "after": "new", "repository": {"full_name": "username/repo_name"}}`) bodyReader := bytes.NewReader(body) - mac := hmac.New(crypto.SHA1.New, config.Cfg.WebHookSecret) + webhookSecret := getWebhookSecret(resp.Id, testAdminCtx).Content.WebhookSecret + + mac := hmac.New(crypto.SHA1.New, []byte(webhookSecret)) mac.Write(body) signature := hex.EncodeToString(mac.Sum(nil)) signature = "sha1=" + signature diff --git a/test/api_project_test.go b/test/api_project_test.go index c28c258..0cc02c6 100644 --- a/test/api_project_test.go +++ b/test/api_project_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "github.com/simon987/task_tracker/api" + "github.com/simon987/task_tracker/storage" "io/ioutil" "net/http" "testing" @@ -465,6 +466,82 @@ func TestPausedProjectShouldNotDispatchTasks(t *testing.T) { }, testProject, testAdminCtx) } +func TestGetWebhookSecret(t *testing.T) { + + resp := getWebhookSecret(testProject, testAdminCtx) + + if resp.Ok != true { + t.Error() + } + if len(resp.Content.WebhookSecret) <= 0 { + t.Error() + } +} + +func TestSetWebhookSecret(t *testing.T) { + + resp1 := setWebhookSecret(api.SetWebhookSecretRequest{ + WebhookSecret: "new", + }, testProject, testAdminCtx) + + if resp1.Ok != true { + t.Error() + } + + resp := getWebhookSecret(testProject, testAdminCtx) + + if resp.Ok != true { + t.Error() + } + if resp.Content.WebhookSecret != "new" { + t.Error() + } +} + +func TestGetWebhookRequiresRole(t *testing.T) { + + otherUser := getSessionCtx("testwebhookrole", "testwebhookrole", false) + otherUserId := getAccountDetails(otherUser).Content.Id + + user := getSessionCtx("testwebhookroleu", "testwebhookroleu", false) + userId := getAccountDetails(user).Content.Id + + resp := setRoleOnProject(api.SetManagerRoleOnProjectRequest{ + Role: storage.RoleEdit | storage.RoleManageAccess | storage.RoleRead, + Manager: otherUserId, + }, testProject, testAdminCtx) + if resp.Ok != true { + t.Fail() + } + resp = setRoleOnProject(api.SetManagerRoleOnProjectRequest{ + Role: storage.RoleSecret, + Manager: userId, + }, testProject, testAdminCtx) + if resp.Ok != true { + t.Fail() + } + + rUser := setWebhookSecret(api.SetWebhookSecretRequest{ + WebhookSecret: "test", + }, testProject, user) + rOther := setWebhookSecret(api.SetWebhookSecretRequest{ + WebhookSecret: "test", + }, testProject, otherUser) + rGuest := setWebhookSecret(api.SetWebhookSecretRequest{ + WebhookSecret: "test", + }, testProject, nil) + + if rUser.Ok != true { + t.Error() + } + if rOther.Ok != false { + t.Error() + } + if rGuest.Ok != false { + t.Error() + } +} + func createProjectAsAdmin(req api.CreateProjectRequest) CreateProjectAR { return createProject(req, testAdminCtx) } @@ -502,3 +579,15 @@ func getProjectList(s *http.Client) (ar ProjectListAR) { UnmarshalResponse(r, &ar) return } + +func getWebhookSecret(pid int64, s *http.Client) (ar WebhookSecretAR) { + r := Get(fmt.Sprintf("/project/webhook_secret/%d", pid), nil, s) + UnmarshalResponse(r, &ar) + return +} + +func setWebhookSecret(req api.SetWebhookSecretRequest, pid int64, s *http.Client) (ar api.JsonResponse) { + r := Post(fmt.Sprintf("/project/webhook_secret/%d", pid), req, nil, s) + UnmarshalResponse(r, &ar) + return +} diff --git a/test/common.go b/test/common.go index a19b6d8..8892f44 100644 --- a/test/common.go +++ b/test/common.go @@ -172,3 +172,19 @@ type ReleaseAR struct { Updated bool `json:"updated"` } `json:"content"` } + +type WebhookSecretAR struct { + Ok bool `json:"ok"` + Message string `json:"message"` + Content struct { + WebhookSecret string `json:"webhook_secret"` + } `json:"content"` +} + +type AccountAR struct { + Ok bool `json:"ok"` + Message string `json:"message"` + Content struct { + *storage.Manager `json:"manager"` + } `json:"content"` +} diff --git a/test/config.yml b/test/config.yml index d4efd92..4fbfaff 100644 --- a/test/config.yml +++ b/test/config.yml @@ -6,7 +6,6 @@ database: log_levels: ["debug", "error", "trace", "info", "warn"] git: - webhook_secret: "very_secret_secret" webhook_hash: "sha1" webhook_sig_header: "X-Hub-Signature" diff --git a/test/schema.sql b/test/schema.sql index 878f063..b8cf304 100755 --- a/test/schema.sql +++ b/test/schema.sql @@ -25,7 +25,8 @@ CREATE TABLE project git_repo TEXT NOT NULL, version TEXT NOT NULL, motd TEXT NOT NULL, - secret TEXT NOT NULL DEFAULT '{}' + secret TEXT NOT NULL DEFAULT '{}', + webhook_secret TEXT NOT NULL ); CREATE TABLE worker_access diff --git a/web/angular/src/app/api.service.ts b/web/angular/src/app/api.service.ts index 80c4f1a..df55562 100755 --- a/web/angular/src/app/api.service.ts +++ b/web/angular/src/app/api.service.ts @@ -106,4 +106,12 @@ export class ApiService { return this.http.post(this.url + `/project/secret/${pid}`, {"secret": secret}) } + getWebhookSecret(pid: number) { + return this.http.get(this.url + `/project/webhook_secret/${pid}`,) + } + + setWebhookSecret(pid: number, secret: string) { + return this.http.post(this.url + `/project/webhook_secret/${pid}`, {"webhook_secret": secret}) + } + } diff --git a/web/angular/src/app/models/manager.ts b/web/angular/src/app/models/manager.ts index ffa2240..94195dd 100644 --- a/web/angular/src/app/models/manager.ts +++ b/web/angular/src/app/models/manager.ts @@ -51,4 +51,16 @@ export class ManagerRoleOnProject { this.role &= ~4 } } + + get secretRole(): boolean { + return (this.role & 8) != 0 + } + + set secretRole(role: boolean) { + if (role) { + this.role |= 8 + } else { + this.role &= ~8 + } + } } 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 0501d84..85b9306 100644 --- a/web/angular/src/app/project-dashboard/project-dashboard.component.ts +++ b/web/angular/src/app/project-dashboard/project-dashboard.component.ts @@ -366,13 +366,14 @@ export class ProjectDashboardComponent implements OnInit { this.dialog.open(AreYouSureComponent, { width: '250px', }).afterClosed().subscribe(result => { - if (result) { - this.project.paused = paused; - this.apiService.updateProject(this.project).subscribe(() => { - this.translate.get("messenger.acknowledged").subscribe(t => - this.messenger.show(t)) - }) - } + this.project.paused = paused; + this.apiService.updateProject(this.project).subscribe(() => { + this.translate.get("messenger.acknowledged").subscribe(t => + this.messenger.show(t)) + }, error => { + this.translate.get("messenger.unauthorized").subscribe(t => + this.messenger.show(t)) + }) }); } diff --git a/web/angular/src/app/project-list/project-list.component.html b/web/angular/src/app/project-list/project-list.component.html index 270edfc..b530eaf 100755 --- a/web/angular/src/app/project-list/project-list.component.html +++ b/web/angular/src/app/project-list/project-list.component.html @@ -33,6 +33,7 @@ diff --git a/web/angular/src/app/project-perms/project-perms.component.html b/web/angular/src/app/project-perms/project-perms.component.html index 4cb384b..d07b6ae 100644 --- a/web/angular/src/app/project-perms/project-perms.component.html +++ b/web/angular/src/app/project-perms/project-perms.component.html @@ -55,6 +55,10 @@ (change)="onRoleChange(m)" [disabled]="m.manager.id==auth.account.id" >{{"perms.manage"|translate}} + {{"perms.secret"|translate}} diff --git a/web/angular/src/app/project-secret/project-secret.component.html b/web/angular/src/app/project-secret/project-secret.component.html index bae32f1..fe73f85 100644 --- a/web/angular/src/app/project-secret/project-secret.component.html +++ b/web/angular/src/app/project-secret/project-secret.component.html @@ -1,22 +1,47 @@
- + + {{"secret.title" | translate}} {{"secret.subtitle" | translate}} + + + {{"secret.secret" | translate}} + + + + + + + - - {{"secret.secret" | translate}} - - + + + {{"secret.webhook_title" | translate}} + {{"secret.webhook_subtitle" | translate}} + + + + {{"secret.webhook_secret" | translate}} + + + + (click)="onWebhookUpdate()">{{"secret.update" | translate}}
diff --git a/web/angular/src/app/project-secret/project-secret.component.ts b/web/angular/src/app/project-secret/project-secret.component.ts index d2ed4f4..6dc123d 100644 --- a/web/angular/src/app/project-secret/project-secret.component.ts +++ b/web/angular/src/app/project-secret/project-secret.component.ts @@ -13,6 +13,7 @@ import {MessengerService} from "../messenger.service"; export class ProjectSecretComponent implements OnInit { secret: string; + webhookSecret: string; projectId: number; constructor(private auth: AuthService, @@ -26,6 +27,7 @@ export class ProjectSecretComponent implements OnInit { this.route.params.subscribe(params => { this.projectId = params["id"]; this.getSecret(); + this.getWebhookSecret(); }); } @@ -37,10 +39,28 @@ export class ProjectSecretComponent implements OnInit { }) } + getWebhookSecret() { + this.apiService.getWebhookSecret(this.projectId).subscribe(data => { + this.webhookSecret = data["content"]["webhook_secret"] + }, error => { + this.translate.get("messenger.unauthorized").subscribe(t => this.messenger.show(t)) + }) + } + onUpdate() { this.apiService.setSecret(this.projectId, this.secret).subscribe(data => { this.translate.get("secret.ok").subscribe(t => this.messenger.show(t)) }) + } + onWebhookUpdate() { + this.apiService.setWebhookSecret(this.projectId, this.webhookSecret).subscribe(data => { + this.translate.get("secret.ok").subscribe(t => this.messenger.show(t)) + }) + } + + refresh() { + this.getWebhookSecret(); + this.getSecret(); } } diff --git a/web/angular/src/assets/i18n/en.json b/web/angular/src/assets/i18n/en.json index 434072f..6f9b888 100644 --- a/web/angular/src/assets/i18n/en.json +++ b/web/angular/src/assets/i18n/en.json @@ -8,7 +8,8 @@ "login": "Login", "worker_dashboard": "Workers", "account": "Account", - "manager_list": "Managers" + "manager_list": "Managers", + "back": "back" }, "logs": { "title": "Logs", @@ -119,6 +120,7 @@ "read": "Read", "edit": "Edit", "manage": "Manage permissions", + "secret": "Configure secrets", "set": "Changes saved", "workers": "Workers", "no_workers": "No workers have explicit access to this project", @@ -152,6 +154,9 @@ "secret": { "title": "Project secret", "subtitle": "You can set project configuration here. It is only accessible by workers with ASSIGN access to this project", + "webhook_title": "Webhook secret", + "webhook_subtitle": "You need to supply this to Github/Gogs for delivery to work", + "webhook_secret": "Webhook secret", "secret": "Secret", "update": "Update", "ok": "Updated" diff --git a/web/angular/src/assets/i18n/fr.json b/web/angular/src/assets/i18n/fr.json index ead804d..c2c53c4 100644 --- a/web/angular/src/assets/i18n/fr.json +++ b/web/angular/src/assets/i18n/fr.json @@ -8,7 +8,8 @@ "login": "Ouvrir un session", "worker_dashboard": "Workers", "account": "Compte", - "manager_list": "Managers" + "manager_list": "Managers", + "back": "Arrière" }, "logs": { "title": "Journaux", @@ -116,11 +117,11 @@ "read": "Lecture", "edit": "Modification", "manage": "Gestion des permissions", + "secret": "Gestion des secrets", "set": "Changements enregistrés", "workers": "Workers", "no_workers": "Aucun Worker n'a explicitement accès à ce projet", - "managers": "Managers", - "secret": "Secret" + "managers": "Managers" }, "messenger": { "close": "Fermer", @@ -148,8 +149,11 @@ "alias": "Alias pertinent" }, "secret": { - "title": "Secret", + "title": "Secret du projet", "subtitle": "Vous pouvez définir la configuration du projet ici. Ce n'est accessible que par les Workers ayant accès au projet", + "webhook_title": "Secret (Webhook)", + "webhook_subtitle": "Vous devez le donner à Github/Gogs.", + "webhook_secret": "Secret (Webhook)", "secret": "Secret", "update": "Mettre à jour", "ok": "Mis à jour"