diff --git a/src/main/scala/app/RepositorySettingsController.scala b/src/main/scala/app/RepositorySettingsController.scala index fff2294..602f337 100644 --- a/src/main/scala/app/RepositorySettingsController.scala +++ b/src/main/scala/app/RepositorySettingsController.scala @@ -8,11 +8,14 @@ import org.scalatra.FlashMapSupport class RepositorySettingsController extends RepositorySettingsControllerBase - with RepositoryService with AccountService with OwnerAuthenticator with UsersAuthenticator + with RepositoryService with AccountService with WebHookService + with OwnerAuthenticator with UsersAuthenticator trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSupport { - self: RepositoryService with AccountService with OwnerAuthenticator with UsersAuthenticator => + self: RepositoryService with AccountService with WebHookService + with OwnerAuthenticator with UsersAuthenticator => + // for repository options case class OptionsForm(description: Option[String], defaultBranch: String, isPrivate: Boolean) val optionsForm = mapping( @@ -20,13 +23,21 @@ "defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100)))), "isPrivate" -> trim(label("Repository Type", boolean())) )(OptionsForm.apply) - + + // for collaborator addition case class CollaboratorForm(userName: String) val collaboratorForm = mapping( "userName" -> trim(label("Username", text(required, collaborator))) )(CollaboratorForm.apply) + // for web hook url addition + case class WebHookForm(url: String) + + val webHookForm = mapping( + "url" -> trim(label("url", text(required, webHook))) + )(WebHookForm.apply) + /** * Redirect to the Options page. */ @@ -92,7 +103,12 @@ * Display the web hook page. */ get("/:owner/:repository/settings/hooks")(ownerOnly { repository => - settings.html.hooks(repository) + settings.html.hooks(getWebHookURLs(repository.owner, repository.name), repository) + }) + + post("/:owner/:repository/settings/hooks/add", webHookForm)(ownerOnly { (form, repository) => + addWebHookURL(repository.owner, repository.name, form.url) + redirect(s"/${repository.owner}/${repository.name}/settings/hooks") }) /** @@ -116,6 +132,16 @@ }) /** + * Provides duplication check for web hook url. + */ + private def webHook: Constraint = new Constraint(){ + override def validate(name: String, value: String): Option[String] = { + val paths = request.getRequestURI.split("/") + getWebHookURLs(paths(1), paths(2)).map(_.url).find(_ == value).map(_ => "URL had been registered already.") + } + } + + /** * Provides Constraint to validate the collaborator name. */ private def collaborator: Constraint = new Constraint(){ diff --git a/src/main/scala/model/WebHook.scala b/src/main/scala/model/WebHook.scala index f143701..63b0fac 100644 --- a/src/main/scala/model/WebHook.scala +++ b/src/main/scala/model/WebHook.scala @@ -6,7 +6,7 @@ def url = column[String]("URL") def * = userName ~ repositoryName ~ url <> (WebHook, WebHook.unapply _) - def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository) + def byPrimaryKey(owner: String, repository: String, url: String) = byRepository(owner, repository) && (this.url is url.bind) } case class WebHook( diff --git a/src/main/scala/service/WebHookService.scala b/src/main/scala/service/WebHookService.scala new file mode 100644 index 0000000..0c050d9 --- /dev/null +++ b/src/main/scala/service/WebHookService.scala @@ -0,0 +1,19 @@ +package service + +import scala.slick.driver.H2Driver.simple._ +import Database.threadLocalSession + +import model._ + +trait WebHookService { + + def getWebHookURLs(owner: String, repository: String): List[WebHook] = + Query(WebHooks).filter(_.byRepository(owner, repository)).sortBy(_.url).list + + def addWebHookURL(owner: String, repository: String, url :String): Unit = + WebHooks.insert(WebHook(owner, repository, url)) + + def deleteWebHookURL(owner: String, repository: String, url :String): Unit = + Query(WebHooks).filter(_.byPrimaryKey(owner, repository, url)).delete + +} diff --git a/src/main/twirl/settings/hooks.scala.html b/src/main/twirl/settings/hooks.scala.html index 6f3ce16..a5c404a 100644 --- a/src/main/twirl/settings/hooks.scala.html +++ b/src/main/twirl/settings/hooks.scala.html @@ -1,10 +1,15 @@ -@(repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) +@(webHooks: List[model.WebHook], repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) @import context._ @import view.helpers._ @html.main("Settings", Some(repository)){ @html.header("settings", repository) @menu("hooks", repository){