mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Webhooks for repo creation/deletion (#1663)
* Webhooks for repo creation/deletion * add createHookTask * Add handles for GetSlackPayload and GetDiscordPayload
This commit is contained in:
		@@ -835,8 +835,8 @@ func wikiRemoteURL(remote string) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MigrateRepository migrates a existing repository from other project hosting.
 | 
			
		||||
func MigrateRepository(u *User, opts MigrateRepoOptions) (*Repository, error) {
 | 
			
		||||
	repo, err := CreateRepository(u, CreateRepoOptions{
 | 
			
		||||
func MigrateRepository(doer, u *User, opts MigrateRepoOptions) (*Repository, error) {
 | 
			
		||||
	repo, err := CreateRepository(doer, u, CreateRepoOptions{
 | 
			
		||||
		Name:        opts.Name,
 | 
			
		||||
		Description: opts.Description,
 | 
			
		||||
		IsPrivate:   opts.IsPrivate,
 | 
			
		||||
@@ -1202,7 +1202,7 @@ func IsUsableRepoName(name string) error {
 | 
			
		||||
	return isUsableName(reservedRepoNames, reservedRepoPatterns, name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
 | 
			
		||||
func createRepository(e *xorm.Session, doer, u *User, repo *Repository) (err error) {
 | 
			
		||||
	if err = IsUsableRepoName(repo.Name); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
@@ -1249,7 +1249,15 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
 | 
			
		||||
			return fmt.Errorf("getOwnerTeam: %v", err)
 | 
			
		||||
		} else if err = t.addRepository(e, repo); err != nil {
 | 
			
		||||
			return fmt.Errorf("addRepository: %v", err)
 | 
			
		||||
		} else if err = prepareWebhooks(e, repo, HookEventRepository, &api.RepositoryPayload{
 | 
			
		||||
			Action:       api.HookRepoCreated,
 | 
			
		||||
			Repository:   repo.APIFormat(AccessModeOwner),
 | 
			
		||||
			Organization: u.APIFormat(),
 | 
			
		||||
			Sender:       doer.APIFormat(),
 | 
			
		||||
		}); err != nil {
 | 
			
		||||
			return fmt.Errorf("prepareWebhooks: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		go HookQueue.Add(repo.ID)
 | 
			
		||||
	} else {
 | 
			
		||||
		// Organization automatically called this in addRepository method.
 | 
			
		||||
		if err = repo.recalculateAccesses(e); err != nil {
 | 
			
		||||
@@ -1266,8 +1274,8 @@ func createRepository(e *xorm.Session, u *User, repo *Repository) (err error) {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CreateRepository creates a repository for given user or organization.
 | 
			
		||||
func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error) {
 | 
			
		||||
// CreateRepository creates a repository for the user/organization u.
 | 
			
		||||
func CreateRepository(doer, u *User, opts CreateRepoOptions) (_ *Repository, err error) {
 | 
			
		||||
	if !u.CanCreateRepo() {
 | 
			
		||||
		return nil, ErrReachLimitOfRepo{u.MaxRepoCreation}
 | 
			
		||||
	}
 | 
			
		||||
@@ -1287,7 +1295,7 @@ func CreateRepository(u *User, opts CreateRepoOptions) (_ *Repository, err error
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = createRepository(sess, u, repo); err != nil {
 | 
			
		||||
	if err = createRepository(sess, doer, u, repo); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1623,7 +1631,7 @@ func UpdateRepositoryUnits(repo *Repository, units []RepoUnit) (err error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteRepository deletes a repository for a user or organization.
 | 
			
		||||
func DeleteRepository(uid, repoID int64) error {
 | 
			
		||||
func DeleteRepository(doer *User, uid, repoID int64) error {
 | 
			
		||||
	// In case is a organization.
 | 
			
		||||
	org, err := GetUserByID(uid)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@@ -1781,6 +1789,18 @@ func DeleteRepository(uid, repoID int64) error {
 | 
			
		||||
		return fmt.Errorf("Commit: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if org.IsOrganization() {
 | 
			
		||||
		if err = PrepareWebhooks(repo, HookEventRepository, &api.RepositoryPayload{
 | 
			
		||||
			Action:       api.HookRepoDeleted,
 | 
			
		||||
			Repository:   repo.APIFormat(AccessModeOwner),
 | 
			
		||||
			Organization: org.APIFormat(),
 | 
			
		||||
			Sender:       doer.APIFormat(),
 | 
			
		||||
		}); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		go HookQueue.Add(repo.ID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1974,7 +1994,7 @@ func gatherMissingRepoRecords() ([]*Repository, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteMissingRepositories deletes all repository records that lost Git files.
 | 
			
		||||
func DeleteMissingRepositories() error {
 | 
			
		||||
func DeleteMissingRepositories(doer *User) error {
 | 
			
		||||
	repos, err := gatherMissingRepoRecords()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("gatherMissingRepoRecords: %v", err)
 | 
			
		||||
@@ -1986,7 +2006,7 @@ func DeleteMissingRepositories() error {
 | 
			
		||||
 | 
			
		||||
	for _, repo := range repos {
 | 
			
		||||
		log.Trace("Deleting %d/%d...", repo.OwnerID, repo.ID)
 | 
			
		||||
		if err := DeleteRepository(repo.OwnerID, repo.ID); err != nil {
 | 
			
		||||
		if err := DeleteRepository(doer, repo.OwnerID, repo.ID); err != nil {
 | 
			
		||||
			if err2 := CreateRepositoryNotice(fmt.Sprintf("DeleteRepository [%d]: %v", repo.ID, err)); err2 != nil {
 | 
			
		||||
				return fmt.Errorf("CreateRepositoryNotice: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
@@ -2226,7 +2246,7 @@ func HasForkedRepo(ownerID, repoID int64) (*Repository, bool) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ForkRepository forks a repository
 | 
			
		||||
func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
 | 
			
		||||
func ForkRepository(doer, u *User, oldRepo *Repository, name, desc string) (_ *Repository, err error) {
 | 
			
		||||
	forkedRepo, err := oldRepo.GetUserFork(u.ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
@@ -2256,7 +2276,7 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (_ *Reposit
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = createRepository(sess, u, repo); err != nil {
 | 
			
		||||
	if err = createRepository(sess, doer, u, repo); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -118,13 +118,12 @@ func TestGetUserFork(t *testing.T) {
 | 
			
		||||
func TestForkRepository(t *testing.T) {
 | 
			
		||||
	assert.NoError(t, PrepareTestDatabase())
 | 
			
		||||
 | 
			
		||||
	// User13 has repo 11 forked from repo10
 | 
			
		||||
	repo, err := GetRepositoryByID(10)
 | 
			
		||||
	assert.NoError(t, err)
 | 
			
		||||
	assert.NotNil(t, repo)
 | 
			
		||||
	// user 13 has already forked repo10
 | 
			
		||||
	user := AssertExistsAndLoadBean(t, &User{ID: 13}).(*User)
 | 
			
		||||
	repo := AssertExistsAndLoadBean(t, &Repository{ID: 10}).(*Repository)
 | 
			
		||||
 | 
			
		||||
	repo, err = ForkRepository(&User{ID: 13}, repo, "test", "test")
 | 
			
		||||
	assert.Nil(t, repo)
 | 
			
		||||
	fork, err := ForkRepository(user, user, repo, "test", "test")
 | 
			
		||||
	assert.Nil(t, fork)
 | 
			
		||||
	assert.Error(t, err)
 | 
			
		||||
	assert.True(t, IsErrRepoAlreadyExist(err))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -68,6 +68,7 @@ type HookEvents struct {
 | 
			
		||||
	Create      bool `json:"create"`
 | 
			
		||||
	Push        bool `json:"push"`
 | 
			
		||||
	PullRequest bool `json:"pull_request"`
 | 
			
		||||
	Repository  bool `json:"repository"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HookEvent represents events that will delivery hook.
 | 
			
		||||
@@ -188,6 +189,12 @@ func (w *Webhook) HasPullRequestEvent() bool {
 | 
			
		||||
		(w.ChooseEvents && w.HookEvents.PullRequest)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasRepositoryEvent returns if hook enabled repository event.
 | 
			
		||||
func (w *Webhook) HasRepositoryEvent() bool {
 | 
			
		||||
	return w.SendEverything ||
 | 
			
		||||
		(w.ChooseEvents && w.HookEvents.Repository)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EventsArray returns an array of hook events
 | 
			
		||||
func (w *Webhook) EventsArray() []string {
 | 
			
		||||
	events := make([]string, 0, 3)
 | 
			
		||||
@@ -246,8 +253,12 @@ func GetWebhookByOrgID(orgID, id int64) (*Webhook, error) {
 | 
			
		||||
 | 
			
		||||
// GetActiveWebhooksByRepoID returns all active webhooks of repository.
 | 
			
		||||
func GetActiveWebhooksByRepoID(repoID int64) ([]*Webhook, error) {
 | 
			
		||||
	return getActiveWebhooksByRepoID(x, repoID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getActiveWebhooksByRepoID(e Engine, repoID int64) ([]*Webhook, error) {
 | 
			
		||||
	webhooks := make([]*Webhook, 0, 5)
 | 
			
		||||
	return webhooks, x.Where("is_active=?", true).
 | 
			
		||||
	return webhooks, e.Where("is_active=?", true).
 | 
			
		||||
		Find(&webhooks, &Webhook{RepoID: repoID})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -259,7 +270,11 @@ func GetWebhooksByRepoID(repoID int64) ([]*Webhook, error) {
 | 
			
		||||
 | 
			
		||||
// GetActiveWebhooksByOrgID returns all active webhooks for an organization.
 | 
			
		||||
func GetActiveWebhooksByOrgID(orgID int64) (ws []*Webhook, err error) {
 | 
			
		||||
	err = x.
 | 
			
		||||
	return getActiveWebhooksByOrgID(x, orgID)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getActiveWebhooksByOrgID(e Engine, orgID int64) (ws []*Webhook, err error) {
 | 
			
		||||
	err = e.
 | 
			
		||||
		Where("org_id=?", orgID).
 | 
			
		||||
		And("is_active=?", true).
 | 
			
		||||
		Find(&ws)
 | 
			
		||||
@@ -379,6 +394,7 @@ const (
 | 
			
		||||
	HookEventCreate      HookEventType = "create"
 | 
			
		||||
	HookEventPush        HookEventType = "push"
 | 
			
		||||
	HookEventPullRequest HookEventType = "pull_request"
 | 
			
		||||
	HookEventRepository  HookEventType = "repository"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HookRequest represents hook task request information.
 | 
			
		||||
@@ -479,13 +495,17 @@ func HookTasks(hookID int64, page int) ([]*HookTask, error) {
 | 
			
		||||
// CreateHookTask creates a new hook task,
 | 
			
		||||
// it handles conversion from Payload to PayloadContent.
 | 
			
		||||
func CreateHookTask(t *HookTask) error {
 | 
			
		||||
	return createHookTask(x, t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createHookTask(e Engine, t *HookTask) error {
 | 
			
		||||
	data, err := t.Payloader.JSONPayload()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	t.UUID = gouuid.NewV4().String()
 | 
			
		||||
	t.PayloadContent = string(data)
 | 
			
		||||
	_, err = x.Insert(t)
 | 
			
		||||
	_, err = e.Insert(t)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -497,6 +517,10 @@ func UpdateHookTask(t *HookTask) error {
 | 
			
		||||
 | 
			
		||||
// PrepareWebhook adds special webhook to task queue for given payload.
 | 
			
		||||
func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Payloader) error {
 | 
			
		||||
	return prepareWebhook(x, w, repo, event, p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func prepareWebhook(e Engine, w *Webhook, repo *Repository, event HookEventType, p api.Payloader) error {
 | 
			
		||||
	switch event {
 | 
			
		||||
	case HookEventCreate:
 | 
			
		||||
		if !w.HasCreateEvent() {
 | 
			
		||||
@@ -510,6 +534,10 @@ func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Pay
 | 
			
		||||
		if !w.HasPullRequestEvent() {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	case HookEventRepository:
 | 
			
		||||
		if !w.HasRepositoryEvent() {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var payloader api.Payloader
 | 
			
		||||
@@ -531,7 +559,7 @@ func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Pay
 | 
			
		||||
		payloader = p
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = CreateHookTask(&HookTask{
 | 
			
		||||
	if err = createHookTask(e, &HookTask{
 | 
			
		||||
		RepoID:      repo.ID,
 | 
			
		||||
		HookID:      w.ID,
 | 
			
		||||
		Type:        w.HookTaskType,
 | 
			
		||||
@@ -548,15 +576,19 @@ func PrepareWebhook(w *Webhook, repo *Repository, event HookEventType, p api.Pay
 | 
			
		||||
 | 
			
		||||
// PrepareWebhooks adds new webhooks to task queue for given payload.
 | 
			
		||||
func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) error {
 | 
			
		||||
	ws, err := GetActiveWebhooksByRepoID(repo.ID)
 | 
			
		||||
	return prepareWebhooks(x, repo, event, p)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p api.Payloader) error {
 | 
			
		||||
	ws, err := getActiveWebhooksByRepoID(e, repo.ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("GetActiveWebhooksByRepoID: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check if repo belongs to org and append additional webhooks
 | 
			
		||||
	if repo.MustOwner().IsOrganization() {
 | 
			
		||||
	if repo.mustOwner(e).IsOrganization() {
 | 
			
		||||
		// get hooks for org
 | 
			
		||||
		orgHooks, err := GetActiveWebhooksByOrgID(repo.OwnerID)
 | 
			
		||||
		orgHooks, err := getActiveWebhooksByOrgID(e, repo.OwnerID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("GetActiveWebhooksByOrgID: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
@@ -568,7 +600,7 @@ func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, w := range ws {
 | 
			
		||||
		if err = PrepareWebhook(w, repo, event, p); err != nil {
 | 
			
		||||
		if err = prepareWebhook(e, w, repo, event, p); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -228,6 +228,37 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, meta *DiscordMeta)
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getDiscordRepositoryPayload(p *api.RepositoryPayload, meta *DiscordMeta) (*DiscordPayload, error) {
 | 
			
		||||
	var title, url string
 | 
			
		||||
	var color int
 | 
			
		||||
	switch p.Action {
 | 
			
		||||
	case api.HookRepoCreated:
 | 
			
		||||
		title = fmt.Sprintf("[%s] Repository created", p.Repository.FullName)
 | 
			
		||||
		url = p.Repository.HTMLURL
 | 
			
		||||
		color = successColor
 | 
			
		||||
	case api.HookRepoDeleted:
 | 
			
		||||
		title = fmt.Sprintf("[%s] Repository deleted", p.Repository.FullName)
 | 
			
		||||
		color = warnColor
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &DiscordPayload{
 | 
			
		||||
		Username:  meta.Username,
 | 
			
		||||
		AvatarURL: meta.IconURL,
 | 
			
		||||
		Embeds: []DiscordEmbed{
 | 
			
		||||
			{
 | 
			
		||||
				Title: title,
 | 
			
		||||
				URL:   url,
 | 
			
		||||
				Color: color,
 | 
			
		||||
				Author: DiscordEmbedAuthor{
 | 
			
		||||
					Name:    p.Sender.UserName,
 | 
			
		||||
					URL:     setting.AppURL + p.Sender.UserName,
 | 
			
		||||
					IconURL: p.Sender.AvatarURL,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetDiscordPayload converts a discord webhook into a DiscordPayload
 | 
			
		||||
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*DiscordPayload, error) {
 | 
			
		||||
	s := new(DiscordPayload)
 | 
			
		||||
@@ -244,6 +275,8 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (*Disc
 | 
			
		||||
		return getDiscordPushPayload(p.(*api.PushPayload), discord)
 | 
			
		||||
	case HookEventPullRequest:
 | 
			
		||||
		return getDiscordPullRequestPayload(p.(*api.PullRequestPayload), discord)
 | 
			
		||||
	case HookEventRepository:
 | 
			
		||||
		return getDiscordRepositoryPayload(p.(*api.RepositoryPayload), discord)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -189,6 +189,30 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) (*S
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getSlackRepositoryPayload(p *api.RepositoryPayload, slack *SlackMeta) (*SlackPayload, error) {
 | 
			
		||||
	senderLink := SlackLinkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)
 | 
			
		||||
	var text, title, attachmentText string
 | 
			
		||||
	switch p.Action {
 | 
			
		||||
	case api.HookRepoCreated:
 | 
			
		||||
		text = fmt.Sprintf("[%s] Repository created by %s", p.Repository.FullName, senderLink)
 | 
			
		||||
		title = p.Repository.HTMLURL
 | 
			
		||||
	case api.HookRepoDeleted:
 | 
			
		||||
		text = fmt.Sprintf("[%s] Repository deleted by %s", p.Repository.FullName, senderLink)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &SlackPayload{
 | 
			
		||||
		Channel:  slack.Channel,
 | 
			
		||||
		Text:     text,
 | 
			
		||||
		Username: slack.Username,
 | 
			
		||||
		IconURL:  slack.IconURL,
 | 
			
		||||
		Attachments: []SlackAttachment{{
 | 
			
		||||
			Color: slack.Color,
 | 
			
		||||
			Title: title,
 | 
			
		||||
			Text:  attachmentText,
 | 
			
		||||
		}},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetSlackPayload converts a slack webhook into a SlackPayload
 | 
			
		||||
func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackPayload, error) {
 | 
			
		||||
	s := new(SlackPayload)
 | 
			
		||||
@@ -205,6 +229,8 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (*SlackP
 | 
			
		||||
		return getSlackPushPayload(p.(*api.PushPayload), slack)
 | 
			
		||||
	case HookEventPullRequest:
 | 
			
		||||
		return getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
 | 
			
		||||
	case HookEventRepository:
 | 
			
		||||
		return getSlackRepositoryPayload(p.(*api.RepositoryPayload), slack)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s, nil
 | 
			
		||||
 
 | 
			
		||||
@@ -124,6 +124,7 @@ type WebhookForm struct {
 | 
			
		||||
	Create      bool
 | 
			
		||||
	Push        bool
 | 
			
		||||
	PullRequest bool
 | 
			
		||||
	Repository  bool
 | 
			
		||||
	Active      bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -892,6 +892,8 @@ settings.event_pull_request = Pull Request
 | 
			
		||||
settings.event_pull_request_desc = Pull request opened, closed, reopened, edited, assigned, unassigned, label updated, label cleared, or synchronized.
 | 
			
		||||
settings.event_push = Push
 | 
			
		||||
settings.event_push_desc = Git push to a repository
 | 
			
		||||
settings.event_repository = Repository
 | 
			
		||||
settings.event_repository_desc = Repository created or deleted
 | 
			
		||||
settings.active = Active
 | 
			
		||||
settings.active_helper = Information about the event which triggered the hook will be sent as well.
 | 
			
		||||
settings.add_hook_success = New webhook has been added.
 | 
			
		||||
 
 | 
			
		||||
@@ -145,7 +145,7 @@ func Dashboard(ctx *context.Context) {
 | 
			
		||||
			err = models.DeleteRepositoryArchives()
 | 
			
		||||
		case cleanMissingRepos:
 | 
			
		||||
			success = ctx.Tr("admin.dashboard.delete_missing_repos_success")
 | 
			
		||||
			err = models.DeleteMissingRepositories()
 | 
			
		||||
			err = models.DeleteMissingRepositories(ctx.User)
 | 
			
		||||
		case gitGCRepos:
 | 
			
		||||
			success = ctx.Tr("admin.dashboard.git_gc_repos_success")
 | 
			
		||||
			err = models.GitGcRepos()
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ func DeleteRepo(ctx *context.Context) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := models.DeleteRepository(repo.MustOwner().ID, repo.ID); err != nil {
 | 
			
		||||
	if err := models.DeleteRepository(ctx.User, repo.MustOwner().ID, repo.ID); err != nil {
 | 
			
		||||
		ctx.Handle(500, "DeleteRepository", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ func CreateFork(ctx *context.APIContext, form api.CreateForkOption) {
 | 
			
		||||
		}
 | 
			
		||||
		forker = org
 | 
			
		||||
	}
 | 
			
		||||
	fork, err := models.ForkRepository(forker, repo, repo.Name, repo.Description)
 | 
			
		||||
	fork, err := models.ForkRepository(ctx.User, forker, repo, repo.Name, repo.Description)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Error(500, "ForkRepository", err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -105,7 +105,7 @@ func Search(ctx *context.APIContext) {
 | 
			
		||||
 | 
			
		||||
// CreateUserRepo create a repository for a user
 | 
			
		||||
func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateRepoOption) {
 | 
			
		||||
	repo, err := models.CreateRepository(owner, models.CreateRepoOptions{
 | 
			
		||||
	repo, err := models.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
 | 
			
		||||
		Name:        opt.Name,
 | 
			
		||||
		Description: opt.Description,
 | 
			
		||||
		Gitignores:  opt.Gitignores,
 | 
			
		||||
@@ -121,7 +121,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
 | 
			
		||||
			ctx.Error(422, "", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			if repo != nil {
 | 
			
		||||
				if err = models.DeleteRepository(ctx.User.ID, repo.ID); err != nil {
 | 
			
		||||
				if err = models.DeleteRepository(ctx.User, ctx.User.ID, repo.ID); err != nil {
 | 
			
		||||
					log.Error(4, "DeleteRepository: %v", err)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -254,7 +254,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo, err := models.MigrateRepository(ctxUser, models.MigrateRepoOptions{
 | 
			
		||||
	repo, err := models.MigrateRepository(ctx.User, ctxUser, models.MigrateRepoOptions{
 | 
			
		||||
		Name:        form.RepoName,
 | 
			
		||||
		Description: form.Description,
 | 
			
		||||
		IsPrivate:   form.Private || setting.Repository.ForcePrivate,
 | 
			
		||||
@@ -263,7 +263,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if repo != nil {
 | 
			
		||||
			if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
			if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
				log.Error(4, "DeleteRepository: %v", errDelete)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -345,7 +345,7 @@ func Delete(ctx *context.APIContext) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := models.DeleteRepository(owner.ID, repo.ID); err != nil {
 | 
			
		||||
	if err := models.DeleteRepository(ctx.User, owner.ID, repo.ID); err != nil {
 | 
			
		||||
		ctx.Error(500, "DeleteRepository", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ func ForkPost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo, err := models.ForkRepository(ctxUser, forkRepo, form.RepoName, form.Description)
 | 
			
		||||
	repo, err := models.ForkRepository(ctx.User, ctxUser, forkRepo, form.RepoName, form.Description)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		ctx.Data["Err_RepoName"] = true
 | 
			
		||||
		switch {
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo, err := models.CreateRepository(ctxUser, models.CreateRepoOptions{
 | 
			
		||||
	repo, err := models.CreateRepository(ctx.User, ctxUser, models.CreateRepoOptions{
 | 
			
		||||
		Name:        form.RepoName,
 | 
			
		||||
		Description: form.Description,
 | 
			
		||||
		Gitignores:  form.Gitignores,
 | 
			
		||||
@@ -143,7 +143,7 @@ func CreatePost(ctx *context.Context, form auth.CreateRepoForm) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if repo != nil {
 | 
			
		||||
		if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
		if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
			log.Error(4, "DeleteRepository: %v", errDelete)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -204,7 +204,7 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo, err := models.MigrateRepository(ctxUser, models.MigrateRepoOptions{
 | 
			
		||||
	repo, err := models.MigrateRepository(ctx.User, ctxUser, models.MigrateRepoOptions{
 | 
			
		||||
		Name:        form.RepoName,
 | 
			
		||||
		Description: form.Description,
 | 
			
		||||
		IsPrivate:   form.Private || setting.Repository.ForcePrivate,
 | 
			
		||||
@@ -218,7 +218,7 @@ func MigratePost(ctx *context.Context, form auth.MigrateRepoForm) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if repo != nil {
 | 
			
		||||
		if errDelete := models.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
		if errDelete := models.DeleteRepository(ctx.User, ctxUser.ID, repo.ID); errDelete != nil {
 | 
			
		||||
			log.Error(4, "DeleteRepository: %v", errDelete)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -314,7 +314,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := models.DeleteRepository(ctx.Repo.Owner.ID, repo.ID); err != nil {
 | 
			
		||||
		if err := models.DeleteRepository(ctx.User, ctx.Repo.Owner.ID, repo.ID); err != nil {
 | 
			
		||||
			ctx.Handle(500, "DeleteRepository", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -121,6 +121,7 @@ func ParseHookEvent(form auth.WebhookForm) *models.HookEvent {
 | 
			
		||||
			Create:      form.Create,
 | 
			
		||||
			Push:        form.Push,
 | 
			
		||||
			PullRequest: form.PullRequest,
 | 
			
		||||
			Repository:  form.Repository,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -52,6 +52,16 @@
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<!-- Repository -->
 | 
			
		||||
		<div class="seven wide column">
 | 
			
		||||
			<div class="field">
 | 
			
		||||
				<div class="ui checkbox">
 | 
			
		||||
					<input class="hidden" name="repository" type="checkbox" tabindex="0" {{if .Webhook.Repository}}checked{{end}}>
 | 
			
		||||
					<label>{{.i18n.Tr "repo.settings.event_repository"}}</label>
 | 
			
		||||
					<span class="help">{{.i18n.Tr "repo.settings.event_repository_desc"}}</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user