mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 00:11:04 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			233 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			233 lines
		
	
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
package gitlab
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
)
 | 
						|
 | 
						|
// EventType represents a Gitlab event type.
 | 
						|
type EventType string
 | 
						|
 | 
						|
// List of available event types.
 | 
						|
const (
 | 
						|
	EventTypeBuild         EventType = "Build Hook"
 | 
						|
	EventTypeIssue         EventType = "Issue Hook"
 | 
						|
	EventConfidentialIssue EventType = "Confidential Issue Hook"
 | 
						|
	EventTypeJob           EventType = "Job Hook"
 | 
						|
	EventTypeMergeRequest  EventType = "Merge Request Hook"
 | 
						|
	EventTypeNote          EventType = "Note Hook"
 | 
						|
	EventConfidentialNote  EventType = "Confidential Note Hook"
 | 
						|
	EventTypePipeline      EventType = "Pipeline Hook"
 | 
						|
	EventTypePush          EventType = "Push Hook"
 | 
						|
	EventTypeSystemHook    EventType = "System Hook"
 | 
						|
	EventTypeTagPush       EventType = "Tag Push Hook"
 | 
						|
	EventTypeWikiPage      EventType = "Wiki Page Hook"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	noteableTypeCommit       = "Commit"
 | 
						|
	noteableTypeMergeRequest = "MergeRequest"
 | 
						|
	noteableTypeIssue        = "Issue"
 | 
						|
	noteableTypeSnippet      = "Snippet"
 | 
						|
)
 | 
						|
 | 
						|
type noteEvent struct {
 | 
						|
	ObjectKind       string `json:"object_kind"`
 | 
						|
	ObjectAttributes struct {
 | 
						|
		NoteableType string `json:"noteable_type"`
 | 
						|
	} `json:"object_attributes"`
 | 
						|
}
 | 
						|
 | 
						|
const eventTypeHeader = "X-Gitlab-Event"
 | 
						|
 | 
						|
// HookEventType returns the event type for the given request.
 | 
						|
func HookEventType(r *http.Request) EventType {
 | 
						|
	return EventType(r.Header.Get(eventTypeHeader))
 | 
						|
}
 | 
						|
 | 
						|
// ParseHook tries to parse both web- and system hooks.
 | 
						|
//
 | 
						|
// Example usage:
 | 
						|
//
 | 
						|
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
//     payload, err := ioutil.ReadAll(r.Body)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     event, err := gitlab.ParseHook(gitlab.HookEventType(r), payload)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     switch event := event.(type) {
 | 
						|
//     case *gitlab.PushEvent:
 | 
						|
//         processPushEvent(event)
 | 
						|
//     case *gitlab.MergeEvent:
 | 
						|
//         processMergeEvent(event)
 | 
						|
//     ...
 | 
						|
//     }
 | 
						|
// }
 | 
						|
//
 | 
						|
func ParseHook(eventType EventType, payload []byte) (event interface{}, err error) {
 | 
						|
	switch eventType {
 | 
						|
	case EventTypeSystemHook:
 | 
						|
		return ParseSystemhook(payload)
 | 
						|
	default:
 | 
						|
		return ParseWebhook(eventType, payload)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// ParseSystemhook parses the event payload. For recognized event types, a
 | 
						|
// value of the corresponding struct type will be returned. An error will be
 | 
						|
// returned for unrecognized event types.
 | 
						|
//
 | 
						|
// Example usage:
 | 
						|
//
 | 
						|
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
//     payload, err := ioutil.ReadAll(r.Body)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     event, err := gitlab.ParseSystemhook(payload)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     switch event := event.(type) {
 | 
						|
//     case *gitlab.PushSystemEvent:
 | 
						|
//         processPushSystemEvent(event)
 | 
						|
//     case *gitlab.MergeSystemEvent:
 | 
						|
//         processMergeSystemEvent(event)
 | 
						|
//     ...
 | 
						|
//     }
 | 
						|
// }
 | 
						|
//
 | 
						|
func ParseSystemhook(payload []byte) (event interface{}, err error) {
 | 
						|
	e := &systemHookEvent{}
 | 
						|
	err = json.Unmarshal(payload, e)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	switch e.EventName {
 | 
						|
	case "push":
 | 
						|
		event = &PushSystemEvent{}
 | 
						|
	case "tag_push":
 | 
						|
		event = &TagPushSystemEvent{}
 | 
						|
	case "repository_update":
 | 
						|
		event = &RepositoryUpdateSystemEvent{}
 | 
						|
	case
 | 
						|
		"project_create",
 | 
						|
		"project_update",
 | 
						|
		"project_destroy",
 | 
						|
		"project_transfer",
 | 
						|
		"project_rename":
 | 
						|
		event = &ProjectSystemEvent{}
 | 
						|
	case
 | 
						|
		"group_create",
 | 
						|
		"group_destroy",
 | 
						|
		"group_rename":
 | 
						|
		event = &GroupSystemEvent{}
 | 
						|
	case
 | 
						|
		"key_create",
 | 
						|
		"key_destroy":
 | 
						|
		event = &KeySystemEvent{}
 | 
						|
	case
 | 
						|
		"user_create",
 | 
						|
		"user_destroy",
 | 
						|
		"user_rename":
 | 
						|
		event = &UserSystemEvent{}
 | 
						|
	case
 | 
						|
		"user_add_to_group",
 | 
						|
		"user_remove_from_group",
 | 
						|
		"user_update_for_group":
 | 
						|
		event = &UserGroupSystemEvent{}
 | 
						|
	case
 | 
						|
		"user_add_to_team",
 | 
						|
		"user_remove_from_team",
 | 
						|
		"user_update_for_team":
 | 
						|
		event = &UserTeamSystemEvent{}
 | 
						|
	default:
 | 
						|
		switch e.ObjectKind {
 | 
						|
		case "merge_request":
 | 
						|
			event = &MergeEvent{}
 | 
						|
		default:
 | 
						|
			return nil, fmt.Errorf("unexpected system hook type %s", e.EventName)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if err := json.Unmarshal(payload, event); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return event, nil
 | 
						|
}
 | 
						|
 | 
						|
// WebhookEventType returns the event type for the given request.
 | 
						|
func WebhookEventType(r *http.Request) EventType {
 | 
						|
	return EventType(r.Header.Get(eventTypeHeader))
 | 
						|
}
 | 
						|
 | 
						|
// ParseWebhook parses the event payload. For recognized event types, a
 | 
						|
// value of the corresponding struct type will be returned. An error will
 | 
						|
// be returned for unrecognized event types.
 | 
						|
//
 | 
						|
// Example usage:
 | 
						|
//
 | 
						|
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
						|
//     payload, err := ioutil.ReadAll(r.Body)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     event, err := gitlab.ParseWebhook(gitlab.HookEventType(r), payload)
 | 
						|
//     if err != nil { ... }
 | 
						|
//     switch event := event.(type) {
 | 
						|
//     case *gitlab.PushEvent:
 | 
						|
//         processPushEvent(event)
 | 
						|
//     case *gitlab.MergeEvent:
 | 
						|
//         processMergeEvent(event)
 | 
						|
//     ...
 | 
						|
//     }
 | 
						|
// }
 | 
						|
//
 | 
						|
func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err error) {
 | 
						|
	switch eventType {
 | 
						|
	case EventTypeBuild:
 | 
						|
		event = &BuildEvent{}
 | 
						|
	case EventTypeIssue, EventConfidentialIssue:
 | 
						|
		event = &IssueEvent{}
 | 
						|
	case EventTypeJob:
 | 
						|
		event = &JobEvent{}
 | 
						|
	case EventTypeMergeRequest:
 | 
						|
		event = &MergeEvent{}
 | 
						|
	case EventTypePipeline:
 | 
						|
		event = &PipelineEvent{}
 | 
						|
	case EventTypePush:
 | 
						|
		event = &PushEvent{}
 | 
						|
	case EventTypeTagPush:
 | 
						|
		event = &TagEvent{}
 | 
						|
	case EventTypeWikiPage:
 | 
						|
		event = &WikiPageEvent{}
 | 
						|
	case EventTypeNote, EventConfidentialNote:
 | 
						|
		note := ¬eEvent{}
 | 
						|
		err := json.Unmarshal(payload, note)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
 | 
						|
		if note.ObjectKind != "note" {
 | 
						|
			return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind)
 | 
						|
		}
 | 
						|
 | 
						|
		switch note.ObjectAttributes.NoteableType {
 | 
						|
		case noteableTypeCommit:
 | 
						|
			event = &CommitCommentEvent{}
 | 
						|
		case noteableTypeMergeRequest:
 | 
						|
			event = &MergeCommentEvent{}
 | 
						|
		case noteableTypeIssue:
 | 
						|
			event = &IssueCommentEvent{}
 | 
						|
		case noteableTypeSnippet:
 | 
						|
			event = &SnippetCommentEvent{}
 | 
						|
		default:
 | 
						|
			return nil, fmt.Errorf("unexpected noteable type %s", note.ObjectAttributes.NoteableType)
 | 
						|
		}
 | 
						|
 | 
						|
	default:
 | 
						|
		return nil, fmt.Errorf("unexpected event type: %s", eventType)
 | 
						|
	}
 | 
						|
 | 
						|
	if err := json.Unmarshal(payload, event); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return event, nil
 | 
						|
}
 |