Move account level web hook settings to account settings

This commit is contained in:
Naoki Takezoe
2017-06-24 14:13:22 +09:00
parent 59c9de9f41
commit 54be93b0da
9 changed files with 223 additions and 208 deletions

View File

@@ -11,22 +11,4 @@
<addPrimaryKey constraintName="IDX_DEPLOY_KEY_PK" tableName="DEPLOY_KEY" columnNames="USER_NAME, REPOSITORY_NAME, DEPLOY_KEY_ID"/> <addPrimaryKey constraintName="IDX_DEPLOY_KEY_PK" tableName="DEPLOY_KEY" columnNames="USER_NAME, REPOSITORY_NAME, DEPLOY_KEY_ID"/>
<addForeignKeyConstraint constraintName="IDX_DEPLOY_KEY_FK0" baseTableName="DEPLOY_KEY" baseColumnNames="USER_NAME, REPOSITORY_NAME" referencedTableName="REPOSITORY" referencedColumnNames="USER_NAME, REPOSITORY_NAME"/> <addForeignKeyConstraint constraintName="IDX_DEPLOY_KEY_FK0" baseTableName="DEPLOY_KEY" baseColumnNames="USER_NAME, REPOSITORY_NAME" referencedTableName="REPOSITORY" referencedColumnNames="USER_NAME, REPOSITORY_NAME"/>
<createTable tableName="ACCOUNT_WEB_HOOK">
<column name="USER_NAME" type="varchar(100)" nullable="false"/>
<column name="URL" type="varchar(200)" nullable="false"/>
<column name="TOKEN" type="varchar(100)" nullable="true"/>
<column name="CTYPE" type="varchar(10)" nullable="true"/>
</createTable>
<addPrimaryKey constraintName="IDX_ACCOUNT_WEB_HOOK_PK" tableName="ACCOUNT_WEB_HOOK" columnNames="USER_NAME, URL"/>
<addForeignKeyConstraint constraintName="IDX_ACCOUNT_WEB_HOOK_FK0" baseTableName="ACCOUNT_WEB_HOOK" baseColumnNames="USER_NAME" referencedTableName="ACCOUNT" referencedColumnNames="USER_NAME"/>
<createTable tableName="ACCOUNT_WEB_HOOK_EVENT">
<column name="USER_NAME" type="varchar(100)" nullable="false"/>
<column name="URL" type="varchar(200)" nullable="false"/>
<column name="EVENT" type="varchar(30)" nullable="false"/>
</createTable>
</changeSet> </changeSet>

View File

@@ -19,4 +19,20 @@
</addColumn> </addColumn>
<addForeignKeyConstraint constraintName="IDX_ISSUE_FK3" baseTableName="ISSUE" baseColumnNames="PRIORITY_ID" referencedTableName="PRIORITY" referencedColumnNames="PRIORITY_ID"/> <addForeignKeyConstraint constraintName="IDX_ISSUE_FK3" baseTableName="ISSUE" baseColumnNames="PRIORITY_ID" referencedTableName="PRIORITY" referencedColumnNames="PRIORITY_ID"/>
<createTable tableName="ACCOUNT_WEB_HOOK">
<column name="USER_NAME" type="varchar(100)" nullable="false"/>
<column name="URL" type="varchar(200)" nullable="false"/>
<column name="TOKEN" type="varchar(100)" nullable="true"/>
<column name="CTYPE" type="varchar(10)" nullable="true"/>
</createTable>
<addPrimaryKey constraintName="IDX_ACCOUNT_WEB_HOOK_PK" tableName="ACCOUNT_WEB_HOOK" columnNames="USER_NAME, URL"/>
<addForeignKeyConstraint constraintName="IDX_ACCOUNT_WEB_HOOK_FK0" baseTableName="ACCOUNT_WEB_HOOK" baseColumnNames="USER_NAME" referencedTableName="ACCOUNT" referencedColumnNames="USER_NAME"/>
<createTable tableName="ACCOUNT_WEB_HOOK_EVENT">
<column name="USER_NAME" type="varchar(100)" nullable="false"/>
<column name="URL" type="varchar(200)" nullable="false"/>
<column name="EVENT" type="varchar(30)" nullable="false"/>
</createTable>
</changeSet> </changeSet>

View File

@@ -170,13 +170,6 @@ trait AccountControllerBase extends AccountManagementControllerBase {
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager })) context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
} }
// Webhooks
case "webhooks" =>
gitbucket.core.account.html.webhook(account,
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
getAccountWebHooks(account.userName)
)
// Repositories // Repositories
case _ => { case _ => {
val members = getGroupMembers(account.userName) val members = getGroupMembers(account.userName)
@@ -321,40 +314,50 @@ trait AccountControllerBase extends AccountManagementControllerBase {
redirect(s"/${userName}/_application") redirect(s"/${userName}/_application")
}) })
get("/:userName/_hooks")(oneselfOnly {
val userName = params("userName")
getAccountByUserName(userName).map { account =>
gitbucket.core.account.html.webhook(account,
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
getAccountWebHooks(account.userName)
)
} getOrElse NotFound()
})
/** /**
* Display the account web hook edit page. * Display the account web hook edit page.
*/ */
get("/:userName/_hooks/new")(oneselfOnly { get("/:userName/_hooks/new")(oneselfOnly {
val userName = params("userName") val userName = params("userName")
getAccountByUserName(userName).map { account => getAccountByUserName(userName).map { account =>
val webhook = AccountWebHook(userName, "", WebHookContentType.FORM, None) val webhook = AccountWebHook(userName, "", WebHookContentType.FORM, None)
html.edithooks(webhook, Set(WebHook.Push), account, if (account.isGroupAccount) Nil else getGroupsByUserName(userName), flash.get("info"), true) html.edithooks(webhook, Set(WebHook.Push), account, if (account.isGroupAccount) Nil else getGroupsByUserName(userName), flash.get("info"), true)
} } getOrElse NotFound()
}) })
/** /**
* Add the account web hook URL. * Add the account web hook URL.
*/ */
post("/:userName/_hooks/new", accountWebHookForm(false))(oneselfOnly { form => post("/:userName/_hooks/new", accountWebHookForm(false))(oneselfOnly { form =>
val userName = params("userName") val userName = params("userName")
addAccountWebHook(userName, form.url, form.events, form.ctype, form.token) addAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
flash += "info" -> s"Webhook ${form.url} created" flash += "info" -> s"Webhook ${form.url} created"
redirect(s"/${userName}?tab=webhooks") redirect(s"/${userName}/_hooks")
}) })
/** /**
* Delete the account web hook URL. * Delete the account web hook URL.
*/ */
get("/:userName/_hooks/delete")(oneselfOnly { get("/:userName/_hooks/delete")(oneselfOnly {
val userName = params("userName") val userName = params("userName")
deleteAccountWebHook(userName, params("url")) deleteAccountWebHook(userName, params("url"))
flash += "info" -> s"Webhook ${params("url")} deleted" flash += "info" -> s"Webhook ${params("url")} deleted"
redirect(s"/${userName}?tab=webhooks") redirect(s"/${userName}/_hooks")
}) })
/** /**
* Display the account web hook edit page. * Display the account web hook edit page.
*/ */
get("/:userName/_hooks/edit")(oneselfOnly { get("/:userName/_hooks/edit")(oneselfOnly {
val userName = params("userName") val userName = params("userName")
getAccountByUserName(userName).map { account => getAccountByUserName(userName).map { account =>
@@ -365,20 +368,20 @@ trait AccountControllerBase extends AccountManagementControllerBase {
}) })
/** /**
* Update account web hook settings. * Update account web hook settings.
*/ */
post("/:userName/_hooks/edit", accountWebHookForm(true))(oneselfOnly { form => post("/:userName/_hooks/edit", accountWebHookForm(true))(oneselfOnly { form =>
val userName = params("userName") val userName = params("userName")
updateAccountWebHook(userName, form.url, form.events, form.ctype, form.token) updateAccountWebHook(userName, form.url, form.events, form.ctype, form.token)
flash += "info" -> s"webhook ${form.url} updated" flash += "info" -> s"webhook ${form.url} updated"
redirect(s"/${userName}?tab=webhooks") redirect(s"/${userName}/_hooks")
}) })
/** /**
* Send the test request to registered account web hook URLs. * Send the test request to registered account web hook URLs.
*/ */
ajaxPost("/:userName/_hooks/test")(oneselfOnly { ajaxPost("/:userName/_hooks/test")(oneselfOnly {
import scala.collection.JavaConverters._ // TODO copied & pasted??
import scala.concurrent.duration._ import scala.concurrent.duration._
import scala.concurrent._ import scala.concurrent._
import scala.util.control.NonFatal import scala.util.control.NonFatal
@@ -413,7 +416,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
"headers" -> _headers(req.getAllHeaders), "headers" -> _headers(req.getAllHeaders),
"payload" -> json "payload" -> json
)).recover(toErrorMap), 20 seconds), )).recover(toErrorMap), 20 seconds),
"responce" -> Await.result(resFuture.map(res => Map( "response" -> Await.result(resFuture.map(res => Map(
"status" -> res.getStatusLine(), "status" -> res.getStatusLine(),
"body" -> EntityUtils.toString(res.getEntity()), "body" -> EntityUtils.toString(res.getEntity()),
"headers" -> _headers(res.getAllHeaders()) "headers" -> _headers(res.getAllHeaders())

View File

@@ -297,7 +297,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
"headers" -> _headers(req.getAllHeaders), "headers" -> _headers(req.getAllHeaders),
"payload" -> json "payload" -> json
)).recover(toErrorMap), 20 seconds), )).recover(toErrorMap), 20 seconds),
"responce" -> Await.result(resFuture.map(res => Map( "response" -> Await.result(resFuture.map(res => Map(
"status" -> res.getStatusLine(), "status" -> res.getStatusLine(),
"body" -> EntityUtils.toString(res.getEntity()), "body" -> EntityUtils.toString(res.getEntity()),
"headers" -> _headers(res.getAllHeaders()) "headers" -> _headers(res.getAllHeaders())

View File

@@ -1,128 +1,131 @@
@(webHook: gitbucket.core.model.AccountWebHook, @(webHook: gitbucket.core.model.AccountWebHook,
events: Set[gitbucket.core.model.WebHook.Event], events: Set[gitbucket.core.model.WebHook.Event],
account: gitbucket.core.model.Account, account: gitbucket.core.model.Account,
groupNames: List[String], groupNames: List[String],
info: Option[Any], info: Option[Any],
create: Boolean)(implicit context: gitbucket.core.controller.Context) create: Boolean)(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers @import gitbucket.core.view.helpers
@import gitbucket.core.model.WebHook._ @import gitbucket.core.model.WebHook._
@import gitbucket.core.model.WebHookContentType @import gitbucket.core.model.WebHookContentType
@check(name: String, event: Event) = { @check(name: String, event: Event) = {
name="@(name).@event.name" value="on" @if(events(event)){checked} name="@(name).@event.name" value="on" @if(events(event)){checked}
} }
@gitbucket.core.account.html.main(account, groupNames, "webhooks"){ @gitbucket.core.html.main("Service Hooks"){
<div class="panel panel-default"> @gitbucket.core.account.html.menu("hooks", context.settings.ssh){
<div class="panel-heading strong">Webhook / Manage webhook</div> <div class="panel panel-default">
<div class="panel-body"> <div class="panel-heading strong">Webhook / Manage webhook</div>
<form method="POST" validate="true"> <div class="panel-body">
<fieldset class="form-group"> <form method="POST" validate="true">
<label class="strong">Payload URL</label> <fieldset class="form-group">
<div> <label class="strong">Payload URL</label>
<span class="error" id="error-url"></span> <div>
</div> <span class="error" id="error-url"></span>
@if(create){
<input type="text" name="url" id="url" value="@webHook.url" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" required />
} else {
<input type="text" value="@webHook.url" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" disabled />
<input type="hidden" value="@webHook.url" name="url" />
}
<button class="btn btn-default" id="test">Test Hook</button>
</fieldset>
<fieldset class="form-group">
<label class="strong">Content type</label>
<div></div>
<select name="ctype">
<option value="@WebHookContentType.FORM.code" @if(webHook.ctype == WebHookContentType.FORM){selected}>@WebHookContentType.FORM.ctype</option>
<option value="@WebHookContentType.JSON.code" @if(webHook.ctype == WebHookContentType.JSON){selected}>@WebHookContentType.JSON.ctype</option>
</select>
</fieldset>
<fieldset class="form-group">
<label class="strong">Security Token</label>
<div></div>
<input type="text" name="token" id="token" placeholder="leave blank for no X-Hub-Signature usage" value="@webHook.token" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" />
</fieldset>
<hr />
<label class="strong">Which events would you like to trigger this webhook?</label>
<div>
<span class="error" id="error-events"></span>
</div>
<!--
<label class="checkbox"><input type="checkbox" @check("events",CommitComment) />Commit comment <small class="help-block">Commit or diff commented on. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Create) />Create <small class="help-block">Branch, or tag created. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Delete) />Delete <small class="help-block">Branch, or tag deleted. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Deployment) />Deployment <small class="help-block">Repository deployed. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",DeploymentStatus) />Deployment status <small class="help-block">Deployment status updated from the API. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Fork) />Fork <small class="help-block">Repository forked. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Gollum) />Gollum <small class="help-block">Wiki page updated. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Member) />Member <small class="help-block">Collaborator added to a non-organization repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",PageBuild) />Page build <small class="help-block">Pages site built. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Public) />Public <small class="help-block">Repository changes from private to public. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Release) />Release <small class="help-block">Release published in a repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",TeamAdd) />Team add <small class="help-block">Team added or modified on a repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Watch) />Watch <small class="help-block">User stars a repository.</small></label>
<label class="checkbox"><input type="checkbox" @check("events",Status) />Status <small class="help-block">Commit status updated from the API. </small> </label>
-->
<label class="checkbox"><input type="checkbox" @check("events",IssueComment) />Issue comment <span class="help-block normal">Issue commented on. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",Issues) />Issues <span class="help-block normal">Issue opened, closed<!-- , assigned, or labeled -->. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",PullRequest) />Pull request <span class="help-block normal">Pull request opened, closed<!-- , assigned, labeled -->, or synchronized. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",PullRequestReviewComment) />Pull request review comment <span class="help-block normal">Pull request diff commented on. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",Push) />Push <span class="help-block normal">Git push to a repository. </span> </label>
<div class="text-right">
@if(!create){
<input type="submit" class="btn btn-success" value="Update webhook" formaction="@helpers.url(account.userName)/_hooks/edit" />
<a href="@helpers.url(account.userName)/_hooks/delete?url=@helpers.urlEncode(webHook.url)" class="btn btn-danger" onclick="return confirm('delete webhook for @webHook.url ?')">
Delete webhook
</a>
} else {
<input type="submit" class="btn btn-success" value="Add webhook" formaction="@helpers.url(account.userName)/_hooks/new" />
}
</div>
</form>
</div>
</div>
<div class="modal" id="test-report-modal" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>WebHook Test</h3>
</div>
<div class="modal-body" style="max-height: 300px; overflow: auto;">
<p>request to <span id="test-modal-url" style="word-break: break-all; word-wrap: break-word; white-space: pre; white-space: pre-wrap;"></span></p>
<div id="test-report" style="display:none">
<ul class="nav nav-tabs" id="test-report-tab">
<li class="active"><a href="#request">Request</a></li>
<li><a href="#response">Response <span class="badge badge-success" id="res-status"></span></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="request">
<div id="req-errors" class="alert alert-error">
ERROR<span id="req-errors-body"></span>
</div>
<div id="req-success" style="display:none">
Headers
<pre id="req-headers"></pre>
Payload
<pre id="req-payload"></pre>
</div>
</div> </div>
<div class="tab-pane" id="response"> @if(create){
<div id="res-errors" class="alert alert-error"> <input type="text" name="url" id="url" value="@webHook.url" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" required />
ERROR<span id="res-errors-body"></span> } else {
</div> <input type="text" value="@webHook.url" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" disabled />
<div id="res-success" style="display:none"> <input type="hidden" value="@webHook.url" name="url" />
Headers }
<pre id="res-headers"></pre> <button class="btn btn-default" id="test">Test Hook</button>
Body </fieldset>
<pre id="res-body"></pre> <fieldset class="form-group">
<label class="strong">Content type</label>
<div></div>
<select name="ctype">
<option value="@WebHookContentType.FORM.code" @if(webHook.ctype == WebHookContentType.FORM){selected}>@WebHookContentType.FORM.ctype</option>
<option value="@WebHookContentType.JSON.code" @if(webHook.ctype == WebHookContentType.JSON){selected}>@WebHookContentType.JSON.ctype</option>
</select>
</fieldset>
<fieldset class="form-group">
<label class="strong">Security Token</label>
<div></div>
<input type="text" name="token" id="token" placeholder="leave blank for no X-Hub-Signature usage" value="@webHook.token" class="form-control" style="display: inline; width: 500px; vertical-align: middle;" />
</fieldset>
<hr />
<label class="strong">Which events would you like to trigger this webhook?</label>
<div>
<span class="error" id="error-events"></span>
</div>
<!--
<label class="checkbox"><input type="checkbox" @check("events",CommitComment) />Commit comment <small class="help-block">Commit or diff commented on. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Create) />Create <small class="help-block">Branch, or tag created. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Delete) />Delete <small class="help-block">Branch, or tag deleted. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Deployment) />Deployment <small class="help-block">Repository deployed. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",DeploymentStatus) />Deployment status <small class="help-block">Deployment status updated from the API. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Fork) />Fork <small class="help-block">Repository forked. </small> </label>
-->
<label class="checkbox"><input type="checkbox" @check("events",Gollum) />Gollum <span class="help-block normal">Wiki page updated. </span> </label>
<!--
<label class="checkbox"><input type="checkbox" @check("events",Member) />Member <small class="help-block">Collaborator added to a non-organization repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",PageBuild) />Page build <small class="help-block">Pages site built. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Public) />Public <small class="help-block">Repository changes from private to public. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Release) />Release <small class="help-block">Release published in a repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",TeamAdd) />Team add <small class="help-block">Team added or modified on a repository. </small> </label>
<label class="checkbox"><input type="checkbox" @check("events",Watch) />Watch <small class="help-block">User stars a repository.</small></label>
<label class="checkbox"><input type="checkbox" @check("events",Status) />Status <small class="help-block">Commit status updated from the API. </small> </label>
-->
<label class="checkbox"><input type="checkbox" @check("events",IssueComment) />Issue comment <span class="help-block normal">Issue commented on. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",Issues) />Issues <span class="help-block normal">Issue opened, closed<!-- , assigned, or labeled -->. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",PullRequest) />Pull request <span class="help-block normal">Pull request opened, closed<!-- , assigned, labeled -->, or synchronized. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",PullRequestReviewComment) />Pull request review comment <span class="help-block normal">Pull request diff commented on. </span> </label>
<label class="checkbox"><input type="checkbox" @check("events",Push) />Push <span class="help-block normal">Git push to a repository. </span> </label>
<div class="text-right">
@if(!create){
<input type="submit" class="btn btn-success" value="Update webhook" formaction="@helpers.url(account.userName)/_hooks/edit" />
<a href="@helpers.url(account.userName)/_hooks/delete?url=@helpers.urlEncode(webHook.url)" class="btn btn-danger" onclick="return confirm('delete webhook for @webHook.url ?')">
Delete webhook
</a>
} else {
<input type="submit" class="btn btn-success" value="Add webhook" formaction="@helpers.url(account.userName)/_hooks/new" />
}
</div>
</form>
</div>
</div>
<div class="modal" id="test-report-modal" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3>WebHook Test</h3>
</div>
<div class="modal-body" style="max-height: 300px; overflow: auto;">
<p>request to <span id="test-modal-url" style="word-break: break-all; word-wrap: break-word; white-space: pre; white-space: pre-wrap;"></span></p>
<div id="test-report" style="display:none">
<ul class="nav nav-tabs" id="test-report-tab">
<li class="active"><a href="#request">Request</a></li>
<li><a href="#response">Response <span class="badge badge-success" id="res-status"></span></a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="request">
<div id="req-errors" class="alert alert-error">
ERROR<span id="req-errors-body"></span>
</div>
<div id="req-success" style="display:none">
Headers
<pre id="req-headers"></pre>
Payload
<pre id="req-payload"></pre>
</div>
</div>
<div class="tab-pane" id="response">
<div id="res-errors" class="alert alert-error">
ERROR<span id="res-errors-body"></span>
</div>
<div id="res-success" style="display:none">
Headers
<pre id="res-headers"></pre>
Body
<pre id="res-body"></pre>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div><!-- /.modal-content -->
</div> </div><!-- /.modal-dialog -->
</div><!-- /.modal-content --> </div><!-- /.modal -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script> <script>
$(function(){ $(function(){
$('#test-report-tab a').click(function (e) { $('#test-report-tab a').click(function (e) {
@@ -154,8 +157,8 @@ $(function(){
//console.log(e); //console.log(e);
$('#test-report-tab a:first').tab('show'); $('#test-report-tab a:first').tab('show');
$("#test-report").show(); $("#test-report").show();
$("#req-success").toggle(e.request&&!e.request.error); $("#req-success").toggle(e.request && !e.request.error);
$("#req-errors").toggle(e.request&&!!e.request.error); $("#req-errors").toggle(e.request && !!e.request.error);
$("#req-errors-body").text(e.request.error); $("#req-errors-body").text(e.request.error);
function headers(h){ function headers(h){
h = h["headers"]; h = h["headers"];
@@ -165,14 +168,14 @@ $(function(){
} }
$("#req-headers").html(headers(e.request)); $("#req-headers").html(headers(e.request));
$("#req-payload").text(e.request && e.request.payload ? JSON.stringify(JSON.parse(e.request.payload),undefined,4) : ""); $("#req-payload").text(e.request && e.request.payload ? JSON.stringify(JSON.parse(e.request.payload),undefined,4) : "");
$("#res-success").toggle(e.responce && !e.responce.error); $("#res-success").toggle(e.response && !e.response.error);
$("#res-errors").toggle(e.responce && !!e.responce.error); $("#res-errors").toggle(e.response && !!e.response.error);
$("#res-errors-body").text(e.responce.error); $("#res-errors-body").text(e.response.error);
var success = !!(e.responce && e.responce.status && /^2\d\d$/.test(e.responce.status.statusCode)); var success = !!(e.response && e.response.status && /^2\d\d$/.test(e.response.status.statusCode));
$("#res-status").text((e.responce && e.responce.status && e.responce.status.statusCode) || "ERROR"); $("#res-status").text((e.response && e.response.status && e.response.status.statusCode) || "ERROR");
$("#res-status").toggleClass("badge-success", success).toggleClass("badge-important", !success); $("#res-status").toggleClass("badge-success", success).toggleClass("badge-important", !success);
$("#res-headers").html(headers(e.responce)); $("#res-headers").html(headers(e.response));
$("#res-body").text(e.responce && e.responce.body ? e.responce.body : ""); $("#res-body").text(e.response && e.response.body ? e.response.body : "");
}, },
error:function (e) { error:function (e) {
if(e) { if(e) {
@@ -188,4 +191,5 @@ $(function(){
}); });
}) })
</script> </script>
}
} }

View File

@@ -43,7 +43,9 @@
} else { } else {
<li@if(active == "activity"){ class="active"}><a href="@helpers.url(account.userName)?tab=activity">Public activity</a></li> <li@if(active == "activity"){ class="active"}><a href="@helpers.url(account.userName)?tab=activity">Public activity</a></li>
} }
@*
<li@if(active == "webhooks"){ class="active"}><a href="@helpers.url(account.userName)?tab=webhooks">Webhooks</a></li> <li@if(active == "webhooks"){ class="active"}><a href="@helpers.url(account.userName)?tab=webhooks">Webhooks</a></li>
*@
@gitbucket.core.plugin.PluginRegistry().getProfileTabs.map { tab => @gitbucket.core.plugin.PluginRegistry().getProfileTabs.map { tab =>
@tab(account, context).map { link => @tab(account, context).map { link =>
<li@if(active == link.id){ class="active"}><a href="@context.path/@link.path">@link.label</a></li> <li@if(active == link.id){ class="active"}><a href="@context.path/@link.path">@link.label</a></li>

View File

@@ -22,6 +22,12 @@
<span>Applications</span> <span>Applications</span>
</a> </a>
</li> </li>
<li class="menu-item-hover @if(active=="hooks"){active}">
<a href="@context.path/@context.loginAccount.get.userName/_hooks">
<i class="menu-icon octicon octicon-plug"></i>
<span>Service Hooks</span>
</a>
</li>
@gitbucket.core.plugin.PluginRegistry().getAccountSettingMenus.map { menu => @gitbucket.core.plugin.PluginRegistry().getAccountSettingMenus.map { menu =>
@menu(context).map { link => @menu(context).map { link =>
<li class="menu-item-hover @if(active==link.id){active}"> <li class="menu-item-hover @if(active==link.id){active}">

View File

@@ -2,38 +2,40 @@
groupNames: List[String], groupNames: List[String],
webHooks: List[(gitbucket.core.model.AccountWebHook, Set[gitbucket.core.model.WebHook.Event])])(implicit context: gitbucket.core.controller.Context) webHooks: List[(gitbucket.core.model.AccountWebHook, Set[gitbucket.core.model.WebHook.Event])])(implicit context: gitbucket.core.controller.Context)
@import gitbucket.core.view.helpers @import gitbucket.core.view.helpers
@gitbucket.core.account.html.main(account, groupNames, "webhooks"){ @gitbucket.core.html.main("Service Hooks"){
<div class="panel panel-default"> @gitbucket.core.account.html.menu("hooks", context.settings.ssh){
<div class="panel-heading strong"> <div class="panel panel-default">
Webhooks <div class="panel-heading strong">
</div> Webhooks
<div class="panel-body"> </div>
<p> <div class="panel-body">
Webhooks allow external services to be notified when certain events happen within your repository. <p>
When the specified events happen, well send a POST request to each of the URLs you provide. Webhooks allow external services to be notified when certain events happen within your repository.
Learn more in <a href="https://github.com/takezoe/gitbucket/wiki/API-WebHook" target="_blank">GitBucket Wiki Webhook Page</a>. When the specified events happen, well send a POST request to each of the URLs you provide.
</p> Learn more in <a href="https://github.com/takezoe/gitbucket/wiki/API-WebHook" target="_blank">GitBucket Wiki Webhook Page</a>.
<a href="@helpers.url(account.userName)/_hooks/new" class="btn btn-success pull-right" style="margin-bottom: 10px;">Add webhook</a> </p>
<a href="@helpers.url(account.userName)/_hooks/new" class="btn btn-success pull-right" style="margin-bottom: 10px;">Add webhook</a>
<table class="table table-condensed" style="margin-bottom:0px;"> <table class="table table-condensed" style="margin-bottom:0px;">
@webHooks.map { case (webHook, events) => @webHooks.map { case (webHook, events) =>
<tr><td style="vertical-align: middle;"> <tr><td style="vertical-align: middle;">
<a href="@helpers.url(account.userName)/_hooks/edit?url=@helpers.urlEncode(webHook.url)" class="css-truncate" style="max-width:360px"> <a href="@helpers.url(account.userName)/_hooks/edit?url=@helpers.urlEncode(webHook.url)" class="css-truncate" style="max-width:360px">
<span class="css-truncate-target">@webHook.url</span> <span class="css-truncate-target">@webHook.url</span>
</a> </a>
<em class="css-truncate" style="max-width: 225px;">(<span class="css-truncate-target">@events.map(_.name).mkString(", ")</span>)</em> <em class="css-truncate" style="max-width: 225px;">(<span class="css-truncate-target">@events.map(_.name).mkString(", ")</span>)</em>
</td><td> </td><td>
<div class="btn-group pull-right"> <div class="btn-group pull-right">
<a href="@helpers.url(account.userName)/_hooks/edit?url=@helpers.urlEncode(webHook.url)" class="btn btn-default"> <a href="@helpers.url(account.userName)/_hooks/edit?url=@helpers.urlEncode(webHook.url)" class="btn btn-default">
<span class="octicon octicon-pencil"></span> <span class="octicon octicon-pencil"></span>
</a> </a>
<a href="@helpers.url(account.userName)/_hooks/delete?url=@helpers.urlEncode(webHook.url)" class="btn btn-danger" onclick="return confirm('delete webhook for @webHook.url ?')"> <a href="@helpers.url(account.userName)/_hooks/delete?url=@helpers.urlEncode(webHook.url)" class="btn btn-danger" onclick="return confirm('delete webhook for @webHook.url ?')">
<span class="octicon octicon-x"></span> <span class="octicon octicon-x"></span>
</a> </a>
</div> </div>
</td></tr> </td></tr>
} }
</table> </table>
</div> </div>
</div> </div>
}
} }

View File

@@ -169,14 +169,14 @@ $(function(){
} }
$("#req-headers").html(headers(e.request)); $("#req-headers").html(headers(e.request));
$("#req-payload").text(e.request && e.request.payload ? JSON.stringify(JSON.parse(e.request.payload),undefined,4) : ""); $("#req-payload").text(e.request && e.request.payload ? JSON.stringify(JSON.parse(e.request.payload),undefined,4) : "");
$("#res-success").toggle(e.responce && !e.responce.error); $("#res-success").toggle(e.response && !e.response.error);
$("#res-errors").toggle(e.responce && !!e.responce.error); $("#res-errors").toggle(e.response && !!e.response.error);
$("#res-errors-body").text(e.responce.error); $("#res-errors-body").text(e.response.error);
var success = !!(e.responce && e.responce.status && /^2\d\d$/.test(e.responce.status.statusCode)); var success = !!(e.response && e.response.status && /^2\d\d$/.test(e.response.status.statusCode));
$("#res-status").text((e.responce && e.responce.status && e.responce.status.statusCode) || "ERROR"); $("#res-status").text((e.response && e.response.status && e.response.status.statusCode) || "ERROR");
$("#res-status").toggleClass("badge-success", success).toggleClass("badge-important", !success); $("#res-status").toggleClass("badge-success", success).toggleClass("badge-important", !success);
$("#res-headers").html(headers(e.responce)); $("#res-headers").html(headers(e.response));
$("#res-body").text(e.responce && e.responce.body ? e.responce.body : ""); $("#res-body").text(e.response && e.response.body ? e.response.body : "");
}, },
error:function (e) { error:function (e) {
if(e) { if(e) {