2014-11-13 10:32:18 +03:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package v1
import (
2014-11-13 20:57:00 +03:00
"encoding/json"
2014-11-15 01:11:30 +03:00
api "github.com/gogits/go-gogs-client"
2014-11-13 10:32:18 +03:00
"github.com/gogits/gogs/models"
2014-11-13 20:57:00 +03:00
"github.com/gogits/gogs/modules/base"
2014-11-13 10:32:18 +03:00
"github.com/gogits/gogs/modules/middleware"
)
2014-11-13 20:57:00 +03:00
// GET /repos/:username/:reponame/hooks
// https://developer.github.com/v3/repos/hooks/#list-hooks
2014-11-13 10:32:18 +03:00
func ListRepoHooks ( ctx * middleware . Context ) {
hooks , err := models . GetWebhooksByRepoId ( ctx . Repo . Repository . Id )
if err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "GetWebhooksByRepoId: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 10:32:18 +03:00
return
}
2014-11-15 01:11:30 +03:00
apiHooks := make ( [ ] * api . Hook , len ( hooks ) )
2014-11-13 10:32:18 +03:00
for i := range hooks {
2014-11-15 01:11:30 +03:00
h := & api . Hook {
2014-11-13 10:32:18 +03:00
Id : hooks [ i ] . Id ,
Type : hooks [ i ] . HookTaskType . Name ( ) ,
Active : hooks [ i ] . IsActive ,
2014-11-13 20:57:00 +03:00
Config : make ( map [ string ] string ) ,
2014-11-13 10:32:18 +03:00
}
// Currently, onle have push event.
2014-11-13 20:57:00 +03:00
h . Events = [ ] string { "push" }
h . Config [ "url" ] = hooks [ i ] . Url
h . Config [ "content_type" ] = hooks [ i ] . ContentType . Name ( )
if hooks [ i ] . HookTaskType == models . SLACK {
s := hooks [ i ] . GetSlackHook ( )
h . Config [ "channel" ] = s . Channel
}
apiHooks [ i ] = h
2014-11-13 10:32:18 +03:00
}
ctx . JSON ( 200 , & apiHooks )
}
2014-11-13 20:57:00 +03:00
// POST /repos/:username/:reponame/hooks
// https://developer.github.com/v3/repos/hooks/#create-a-hook
2014-12-13 04:30:32 +03:00
func CreateRepoHook ( ctx * middleware . Context , form api . CreateHookOption ) {
2014-11-13 20:57:00 +03:00
if ! models . IsValidHookTaskType ( form . Type ) {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 422 , & base . ApiJsonErr { "invalid hook type" , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
for _ , name := range [ ] string { "url" , "content_type" } {
if _ , ok := form . Config [ name ] ; ! ok {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 422 , & base . ApiJsonErr { "missing config option: " + name , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
}
if ! models . IsValidHookContentType ( form . Config [ "content_type" ] ) {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 422 , & base . ApiJsonErr { "invalid content type" , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
w := & models . Webhook {
RepoId : ctx . Repo . Repository . Id ,
Url : form . Config [ "url" ] ,
ContentType : models . ToHookContentType ( form . Config [ "content_type" ] ) ,
Secret : form . Config [ "secret" ] ,
HookEvent : & models . HookEvent {
PushOnly : true , // Only support it now.
} ,
IsActive : form . Active ,
HookTaskType : models . ToHookTaskType ( form . Type ) ,
}
if w . HookTaskType == models . SLACK {
channel , ok := form . Config [ "channel" ]
if ! ok {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 422 , & base . ApiJsonErr { "missing config option: channel" , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
meta , err := json . Marshal ( & models . Slack {
Channel : channel ,
} )
if err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "slack: JSON marshal failed: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
w . Meta = string ( meta )
}
if err := w . UpdateEvent ( ) ; err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "UpdateEvent: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
} else if err := models . CreateWebhook ( w ) ; err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "CreateWebhook: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
2014-11-18 19:07:16 +03:00
apiHook := & api . Hook {
Id : w . Id ,
Type : w . HookTaskType . Name ( ) ,
Events : [ ] string { "push" } ,
Active : w . IsActive ,
Config : map [ string ] string {
"url" : w . Url ,
"content_type" : w . ContentType . Name ( ) ,
} ,
}
if w . HookTaskType == models . SLACK {
s := w . GetSlackHook ( )
apiHook . Config [ "channel" ] = s . Channel
}
ctx . JSON ( 201 , apiHook )
2014-11-13 20:57:00 +03:00
}
// PATCH /repos/:username/:reponame/hooks/:id
// https://developer.github.com/v3/repos/hooks/#edit-a-hook
2014-12-13 04:30:32 +03:00
func EditRepoHook ( ctx * middleware . Context , form api . EditHookOption ) {
2014-11-13 20:57:00 +03:00
w , err := models . GetWebhookById ( ctx . ParamsInt64 ( ":id" ) )
if err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "GetWebhookById: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
if form . Config != nil {
if url , ok := form . Config [ "url" ] ; ok {
w . Url = url
}
if ct , ok := form . Config [ "content_type" ] ; ok {
if ! models . IsValidHookContentType ( ct ) {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 422 , & base . ApiJsonErr { "invalid content type" , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
w . ContentType = models . ToHookContentType ( ct )
}
if w . HookTaskType == models . SLACK {
if channel , ok := form . Config [ "channel" ] ; ok {
meta , err := json . Marshal ( & models . Slack {
Channel : channel ,
} )
if err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "slack: JSON marshal failed: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
w . Meta = string ( meta )
}
}
}
if form . Active != nil {
w . IsActive = * form . Active
}
// FIXME: edit events
if err := models . UpdateWebhook ( w ) ; err != nil {
2014-11-15 01:11:30 +03:00
ctx . JSON ( 500 , & base . ApiJsonErr { "UpdateWebhook: " + err . Error ( ) , base . DOC_URL } )
2014-11-13 20:57:00 +03:00
return
}
ctx . JSON ( 200 , map [ string ] interface { } {
"ok" : true ,
} )
}