Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
* upstream/main:
  feat(API): update and delete secret for managing organization secrets (go-gitea#26660)
  Remove ref name in PR commits page (go-gitea#25876)
  Modify the content format of the Feishu webhook (go-gitea#25106)
  Handle "comment form combo editor init" more gracefully (go-gitea#26688)
  Prefer variables over subprocesses (go-gitea#26690)
  Fix archived unix time when archiving the label (go-gitea#26681)
  Make "link-action" backend code respond correct JSON content (go-gitea#26680)
  Fix doubled box-shadow in branch dropdown menu (go-gitea#26678)
  Refactor toast module (go-gitea#26677)
  • Loading branch information
zjjhot committed Aug 24, 2023
2 parents 95a1333 + b62c8e7 commit d3d583f
Show file tree
Hide file tree
Showing 28 changed files with 422 additions and 61 deletions.
6 changes: 3 additions & 3 deletions docs/content/usage/actions/act-runner.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ docker run --entrypoint="" --rm -it gitea/act_runner:latest act_runner generate-
When you are using the docker image, you can specify the configuration file by using the `CONFIG_FILE` environment variable. Make sure that the file is mounted into the container as a volume:

```bash
docker run -v $(pwd)/config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml ...
docker run -v $PWD/config.yaml:/config.yaml -e CONFIG_FILE=/config.yaml ...
```

You may notice the commands above are both incomplete, because it is not the time to run the act runner yet.
Expand Down Expand Up @@ -157,8 +157,8 @@ If you are using the docker image, behaviour will be slightly different. Registr

```bash
docker run \
-v $(pwd)/config.yaml:/config.yaml \
-v $(pwd)/data:/data \
-v $PWD/config.yaml:/config.yaml \
-v $PWD/data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-e CONFIG_FILE=/config.yaml \
-e GITEA_INSTANCE_URL=<instance_url> \
Expand Down
7 changes: 4 additions & 3 deletions models/issues/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ func (l *Label) CalOpenIssues() {

// SetArchived set the label as archived
func (l *Label) SetArchived(isArchived bool) {
if isArchived && l.ArchivedUnix.IsZero() {
l.ArchivedUnix = timeutil.TimeStampNow()
} else {
if !isArchived {
l.ArchivedUnix = timeutil.TimeStamp(0)
} else if isArchived && l.ArchivedUnix.IsZero() {
// Only change the date when it is newly archived.
l.ArchivedUnix = timeutil.TimeStampNow()
}
}

Expand Down
67 changes: 67 additions & 0 deletions models/secret/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ package secret
import (
"context"
"errors"
"fmt"
"strings"

"code.gitea.io/gitea/models/db"
secret_module "code.gitea.io/gitea/modules/secret"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"

"xorm.io/builder"
)
Expand All @@ -26,6 +28,25 @@ type Secret struct {
CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
}

// ErrSecretNotFound represents a "secret not found" error.
type ErrSecretNotFound struct {
Name string
}

// IsErrSecretNotFound checks if an error is a ErrSecretNotFound.
func IsErrSecretNotFound(err error) bool {
_, ok := err.(ErrSecretNotFound)
return ok
}

func (err ErrSecretNotFound) Error() string {
return fmt.Sprintf("secret was not found [name: %s]", err.Name)
}

func (err ErrSecretNotFound) Unwrap() error {
return util.ErrNotExist
}

// newSecret Creates a new already encrypted secret
func newSecret(ownerID, repoID int64, name, data string) *Secret {
return &Secret{
Expand Down Expand Up @@ -93,3 +114,49 @@ func FindSecrets(ctx context.Context, opts FindSecretsOptions) ([]*Secret, error
func CountSecrets(ctx context.Context, opts *FindSecretsOptions) (int64, error) {
return db.GetEngine(ctx).Where(opts.toConds()).Count(new(Secret))
}

// UpdateSecret changes org or user reop secret.
func UpdateSecret(ctx context.Context, orgID, repoID int64, name, data string) error {
sc := new(Secret)
name = strings.ToUpper(name)
has, err := db.GetEngine(ctx).
Where("owner_id=?", orgID).
And("repo_id=?", repoID).
And("name=?", name).
Get(sc)
if err != nil {
return err
} else if !has {
return ErrSecretNotFound{Name: name}
}

encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data)
if err != nil {
return err
}

sc.Data = encrypted
_, err = db.GetEngine(ctx).ID(sc.ID).Cols("data").Update(sc)
return err
}

// DeleteSecret deletes secret from an organization.
func DeleteSecret(ctx context.Context, orgID, repoID int64, name string) error {
sc := new(Secret)
has, err := db.GetEngine(ctx).
Where("owner_id=?", orgID).
And("repo_id=?", repoID).
And("name=?", strings.ToUpper(name)).
Get(sc)
if err != nil {
return err
} else if !has {
return ErrSecretNotFound{Name: name}
}

if _, err := db.GetEngine(ctx).ID(sc.ID).Delete(new(Secret)); err != nil {
return fmt.Errorf("Delete: %w", err)
}

return nil
}
9 changes: 9 additions & 0 deletions modules/structs/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ type CreateSecretOption struct {
// Data of the secret to create
Data string `json:"data" binding:"Required"`
}

// UpdateSecretOption options when updating secret
// swagger:model
type UpdateSecretOption struct {
// Data of the secret to update
//
// required: true
Data string `json:"data" binding:"Required"`
}
3 changes: 3 additions & 0 deletions routers/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,9 @@ func Routes() *web.Route {
m.Group("/actions/secrets", func() {
m.Get("", reqToken(), reqOrgOwnership(), org.ListActionsSecrets)
m.Post("", reqToken(), reqOrgOwnership(), bind(api.CreateSecretOption{}), org.CreateOrgSecret)
m.Combo("/{secretname}").
Put(reqToken(), reqOrgOwnership(), bind(api.UpdateSecretOption{}), org.UpdateOrgSecret).
Delete(reqToken(), reqOrgOwnership(), org.DeleteOrgSecret)
})
m.Group("/public_members", func() {
m.Get("", org.ListPublicMembers)
Expand Down
91 changes: 91 additions & 0 deletions routers/api/v1/org/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ func CreateOrgSecret(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"
opt := web.GetForm(ctx).(*api.CreateSecretOption)
if err := actions.NameRegexMatch(opt.Name); err != nil {
ctx.Error(http.StatusBadRequest, "CreateOrgSecret", err)
return
}
s, err := secret_model.InsertEncryptedSecret(
ctx, ctx.Org.Organization.ID, 0, opt.Name, actions.ReserveLineBreakForTextarea(opt.Data),
)
Expand All @@ -113,3 +117,90 @@ func CreateOrgSecret(ctx *context.APIContext) {

ctx.JSON(http.StatusCreated, convert.ToSecret(s))
}

// UpdateOrgSecret update one secret of the organization
func UpdateOrgSecret(ctx *context.APIContext) {
// swagger:operation PUT /orgs/{org}/actions/secrets/{secretname} organization updateOrgSecret
// ---
// summary: Update a secret value in an organization
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of organization
// type: string
// required: true
// - name: secretname
// in: path
// description: name of the secret
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/UpdateSecretOption"
// responses:
// "204":
// description: update one secret of the organization
// "403":
// "$ref": "#/responses/forbidden"
secretName := ctx.Params(":secretname")
opt := web.GetForm(ctx).(*api.UpdateSecretOption)
err := secret_model.UpdateSecret(
ctx, ctx.Org.Organization.ID, 0, secretName, opt.Data,
)
if secret_model.IsErrSecretNotFound(err) {
ctx.NotFound(err)
return
}
if err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateSecret", err)
return
}

ctx.Status(http.StatusNoContent)
}

// DeleteOrgSecret delete one secret of the organization
func DeleteOrgSecret(ctx *context.APIContext) {
// swagger:operation DELETE /orgs/{org}/actions/secrets/{secretname} organization deleteOrgSecret
// ---
// summary: Delete a secret in an organization
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of organization
// type: string
// required: true
// - name: secretname
// in: path
// description: name of the secret
// type: string
// required: true
// responses:
// "204":
// description: delete one secret of the organization
// "403":
// "$ref": "#/responses/forbidden"
secretName := ctx.Params(":secretname")
err := secret_model.DeleteSecret(
ctx, ctx.Org.Organization.ID, 0, secretName,
)
if secret_model.IsErrSecretNotFound(err) {
ctx.NotFound(err)
return
}
if err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteSecret", err)
return
}

ctx.Status(http.StatusNoContent)
}
3 changes: 3 additions & 0 deletions routers/api/v1/swagger/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,7 @@ type swaggerParameterBodies struct {

// in:body
CreateSecretOption api.CreateSecretOption

// in:body
UpdateSecretOption api.UpdateSecretOption
}
2 changes: 1 addition & 1 deletion routers/web/admin/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,5 +480,5 @@ func DeleteAvatar(ctx *context.Context) {
ctx.Flash.Error(err.Error())
}

ctx.Redirect(setting.AppSubURL + "/admin/users/" + strconv.FormatInt(u.ID, 10))
ctx.JSONRedirect(setting.AppSubURL + "/admin/users/" + strconv.FormatInt(u.ID, 10))
}
2 changes: 1 addition & 1 deletion routers/web/org/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func SettingsDeleteAvatar(ctx *context.Context) {
ctx.Flash.Error(err.Error())
}

ctx.Redirect(ctx.Org.OrgLink + "/settings")
ctx.JSONRedirect(ctx.Org.OrgLink + "/settings")
}

// SettingsDelete response for deleting an organization
Expand Down
5 changes: 1 addition & 4 deletions routers/web/repo/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ func Commits(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName

pager := context.NewPagination(int(commitsCount), pageSize, page, 5)
pager.SetDefaultParams(ctx)
Expand Down Expand Up @@ -157,7 +156,7 @@ func Graph(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName

paginator := context.NewPagination(int(graphCommitsCount), setting.UI.GraphMaxCommitNum, page, 5)
paginator.AddParam(ctx, "mode", "Mode")
paginator.AddParam(ctx, "hide-pr-refs", "HidePRRefs")
Expand Down Expand Up @@ -203,7 +202,6 @@ func SearchCommits(ctx *context.Context) {
}
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["RefName"] = ctx.Repo.RefName
ctx.HTML(http.StatusOK, tplCommits)
}

Expand Down Expand Up @@ -247,7 +245,6 @@ func FileHistory(ctx *context.Context) {
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
ctx.Data["FileName"] = fileName
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName

pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/setting/avatar.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ func SettingsDeleteAvatar(ctx *context.Context) {
if err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository); err != nil {
ctx.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err))
}
ctx.Redirect(ctx.Repo.RepoLink + "/settings")
ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings")
}
2 changes: 1 addition & 1 deletion routers/web/user/setting/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func DeleteAvatar(ctx *context.Context) {
ctx.Flash.Error(err.Error())
}

ctx.Redirect(setting.AppSubURL + "/user/settings")
ctx.JSONRedirect(setting.AppSubURL + "/user/settings")
}

// Organization render all the organization of the user
Expand Down
35 changes: 26 additions & 9 deletions services/webhook/feishu.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,23 +97,40 @@ func (f *FeishuPayload) Push(p *api.PushPayload) (api.Payloader, error) {

// Issue implements PayloadConvertor Issue method
func (f *FeishuPayload) Issue(p *api.IssuePayload) (api.Payloader, error) {
text, issueTitle, attachmentText, _ := getIssuesPayloadInfo(p, noneLinkFormatter, true)

return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil
title, link, by, operator, result, assignees := getIssuesInfo(p)
var res api.Payloader
if assignees != "" {
if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.Issue.Body))
} else {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.Issue.Body))
}
} else {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Issue.Body))
}
return res, nil
}

// IssueComment implements PayloadConvertor IssueComment method
func (f *FeishuPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error) {
text, issueTitle, _ := getIssueCommentPayloadInfo(p, noneLinkFormatter, true)

return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + p.Comment.Body), nil
title, link, by, operator := getIssuesCommentInfo(p)
return newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.Comment.Body)), nil
}

// PullRequest implements PayloadConvertor PullRequest method
func (f *FeishuPayload) PullRequest(p *api.PullRequestPayload) (api.Payloader, error) {
text, issueTitle, attachmentText, _ := getPullRequestPayloadInfo(p, noneLinkFormatter, true)

return newFeishuTextPayload(issueTitle + "\r\n" + text + "\r\n\r\n" + attachmentText), nil
title, link, by, operator, result, assignees := getPullRequestInfo(p)
var res api.Payloader
if assignees != "" {
if p.Action == api.HookIssueAssigned || p.Action == api.HookIssueUnassigned || p.Action == api.HookIssueMilestoned {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, result, assignees, p.PullRequest.Body))
} else {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, assignees, p.PullRequest.Body))
}
} else {
res = newFeishuTextPayload(fmt.Sprintf("%s\n%s\n%s\n%s\n\n%s", title, link, by, operator, p.PullRequest.Body))
}
return res, nil
}

// Review implements PayloadConvertor Review method
Expand Down
Loading

0 comments on commit d3d583f

Please sign in to comment.