mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-30 19:08:37 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			234 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			234 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 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
 | |
| }
 |