mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-05-08 13:55:59 +02:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdd83a84fd | ||
|
|
ef38855b4b | ||
|
|
9bc8db5a15 | ||
|
|
c53f3843b8 | ||
|
|
56f1f5d47f | ||
|
|
d74ef599d3 | ||
|
|
398c77e277 | ||
|
|
99e562e9e6 | ||
|
|
47bdb8da23 | ||
|
|
869930165c | ||
|
|
d0f052e056 | ||
|
|
afd2325678 |
@@ -22,7 +22,7 @@ object MyBuild extends Build {
|
||||
scalaVersion := ScalaVersion,
|
||||
resolvers += Classpaths.typesafeReleases,
|
||||
libraryDependencies ++= Seq(
|
||||
"org.eclipse.jgit" % "org.eclipse.jgit.http.server" % "2.3.1.201302201838-r",
|
||||
"org.eclipse.jgit" % "org.eclipse.jgit.http.server" % "3.0.0.201306101825-r",
|
||||
"org.apache.commons" % "commons-io" % "1.3.2",
|
||||
"org.scalatra" %% "scalatra" % ScalatraVersion,
|
||||
"org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
|
||||
|
||||
8
src/main/resources/update/1_1.sql
Normal file
8
src/main/resources/update/1_1.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
-- Fix COLLABORATOR constraints
|
||||
ALTER TABLE COLLABORATOR DROP CONSTRAINT IDX_COLLABORATOR_FK1 IF EXISTS;
|
||||
ALTER TABLE COLLABORATOR DROP CONSTRAINT IDX_COLLABORATOR_FK0 IF EXISTS;
|
||||
ALTER TABLE COLLABORATOR DROP CONSTRAINT IDX_COLLABORATOR_PK IF EXISTS;
|
||||
|
||||
ALTER TABLE COLLABORATOR ADD CONSTRAINT IDX_COLLABORATOR_PK PRIMARY KEY (USER_NAME, REPOSITORY_NAME, COLLABORATOR_NAME);
|
||||
ALTER TABLE COLLABORATOR ADD CONSTRAINT IDX_COLLABORATOR_FK0 FOREIGN KEY (USER_NAME, REPOSITORY_NAME) REFERENCES REPOSITORY (USER_NAME, REPOSITORY_NAME);
|
||||
ALTER TABLE COLLABORATOR ADD CONSTRAINT IDX_COLLABORATOR_FK1 FOREIGN KEY (COLLABORATOR_NAME) REFERENCES ACCOUNT (USER_NAME);
|
||||
@@ -16,15 +16,15 @@ trait AccountControllerBase extends ControllerBase {
|
||||
case class AccountEditForm(password: Option[String], mailAddress: String, url: Option[String])
|
||||
|
||||
val newForm = mapping(
|
||||
"userName" -> trim(label("User name" , text(required, maxlength(100), identifier, unique))),
|
||||
"userName" -> trim(label("User name" , text(required, maxlength(100), identifier, uniqueUserName))),
|
||||
"password" -> trim(label("Password" , text(required, maxlength(20)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress()))),
|
||||
"url" -> trim(label("URL" , optional(text(maxlength(200)))))
|
||||
)(AccountNewForm.apply)
|
||||
|
||||
val editForm = mapping(
|
||||
"password" -> trim(label("Password" , optional(text(maxlength(20))))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress("userName")))),
|
||||
"url" -> trim(label("URL" , optional(text(maxlength(200)))))
|
||||
)(AccountEditForm.apply)
|
||||
|
||||
@@ -67,9 +67,18 @@ trait AccountControllerBase extends ControllerBase {
|
||||
} else NotFound
|
||||
}
|
||||
|
||||
private def unique: Constraint = new Constraint(){
|
||||
// TODO Merge with UserManagementController
|
||||
private def uniqueUserName: Constraint = new Constraint(){
|
||||
def validate(name: String, value: String): Option[String] =
|
||||
getAccountByUserName(value).map { _ => "User already exists." }
|
||||
}
|
||||
|
||||
// TODO Merge with UserManagementController
|
||||
private def uniqueMailAddress(paramName: String = ""): Constraint = new Constraint(){
|
||||
def validate(name: String, value: String): Option[String] =
|
||||
getAccountByMailAddress(value)
|
||||
.filter { x => if(paramName.isEmpty) true else Some(x.userName) != params.get(paramName) }
|
||||
.map { _ => "Mail address is already registered." }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ trait MilestonesControllerBase extends ControllerBase {
|
||||
post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(collaboratorsOnly { (form, repository) =>
|
||||
getMilestone(repository.owner, repository.name, params("milestoneId").toInt).map { milestone =>
|
||||
updateMilestone(milestone.copy(title = form.title, description = form.description, dueDate = form.dueDate))
|
||||
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.repository))
|
||||
redirect("/%s/%s/issues/milestones".format(repository.owner, repository.name))
|
||||
} getOrElse NotFound
|
||||
})
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ trait SettingsControllerBase extends ControllerBase {
|
||||
*/
|
||||
post("/:owner/:repository/settings/options", optionsForm)(ownerOnly { (form, repository) =>
|
||||
saveRepositoryOptions(repository.owner, repository.name, form.description, form.defaultBranch, form.isPrivate)
|
||||
redirect("%s/%s/settings/options".format(repository.owner, repository.name))
|
||||
redirect("/%s/%s/settings/options".format(repository.owner, repository.name))
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,9 +13,9 @@ trait UserManagementControllerBase extends ControllerBase { self: AccountService
|
||||
case class UserEditForm(userName: String, password: Option[String], mailAddress: String, isAdmin: Boolean, url: Option[String])
|
||||
|
||||
val newForm = mapping(
|
||||
"userName" -> trim(label("Username" , text(required, maxlength(100), identifier, unique))),
|
||||
"userName" -> trim(label("Username" , text(required, maxlength(100), identifier, uniqueUserName))),
|
||||
"password" -> trim(label("Password" , text(required, maxlength(20)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress()))),
|
||||
"isAdmin" -> trim(label("User Type" , boolean())),
|
||||
"url" -> trim(label("URL" , optional(text(maxlength(200)))))
|
||||
)(UserNewForm.apply)
|
||||
@@ -23,7 +23,7 @@ trait UserManagementControllerBase extends ControllerBase { self: AccountService
|
||||
val editForm = mapping(
|
||||
"userName" -> trim(label("Username" , text(required, maxlength(100), identifier))),
|
||||
"password" -> trim(label("Password" , optional(text(maxlength(20))))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100)))),
|
||||
"mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress("userName")))),
|
||||
"isAdmin" -> trim(label("User Type" , boolean())),
|
||||
"url" -> trim(label("URL" , optional(text(maxlength(200)))))
|
||||
)(UserEditForm.apply)
|
||||
@@ -59,9 +59,18 @@ trait UserManagementControllerBase extends ControllerBase { self: AccountService
|
||||
} getOrElse NotFound
|
||||
})
|
||||
|
||||
private def unique: Constraint = new Constraint(){
|
||||
// TODO Merge with AccountController?
|
||||
private def uniqueUserName: Constraint = new Constraint(){
|
||||
def validate(name: String, value: String): Option[String] =
|
||||
getAccountByUserName(value).map { _ => "User already exists." }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Merge with AccountController?
|
||||
private def uniqueMailAddress(paramName: String = ""): Constraint = new Constraint(){
|
||||
def validate(name: String, value: String): Option[String] =
|
||||
getAccountByMailAddress(value)
|
||||
.filter { x => if(paramName.isEmpty) true else Some(x.userName) != params.get(paramName) }
|
||||
.map { _ => "Mail address is already registered." }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,10 @@ trait AccountService {
|
||||
|
||||
def getAccountByUserName(userName: String): Option[Account] =
|
||||
Query(Accounts) filter(_.userName is userName.bind) firstOption
|
||||
|
||||
|
||||
def getAccountByMailAddress(mailAddress: String): Option[Account] =
|
||||
Query(Accounts) filter(_.mailAddress is mailAddress.bind) firstOption
|
||||
|
||||
def getAllUsers(): List[Account] = Query(Accounts) sortBy(_.userName) list
|
||||
|
||||
def createAccount(userName: String, password: String, mailAddress: String, isAdmin: Boolean, url: Option[String]): Unit =
|
||||
|
||||
@@ -36,8 +36,12 @@ trait RepositoryService { self: AccountService =>
|
||||
|
||||
def deleteRepository(userName: String, repositoryName: String): Unit = {
|
||||
Collaborators .filter(_.byRepository(userName, repositoryName)).delete
|
||||
IssueId .filter(_.byRepository(userName, repositoryName)).delete
|
||||
IssueLabels .filter(_.byRepository(userName, repositoryName)).delete
|
||||
Labels .filter(_.byRepository(userName, repositoryName)).delete
|
||||
IssueComments .filter(_.byRepository(userName, repositoryName)).delete
|
||||
Issues .filter(_.byRepository(userName, repositoryName)).delete
|
||||
IssueId .filter(_.byRepository(userName, repositoryName)).delete
|
||||
Milestones .filter(_.byRepository(userName, repositoryName)).delete
|
||||
Repositories .filter(_.byRepository(userName, repositoryName)).delete
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ object AutoUpdate {
|
||||
* Version of GitBucket
|
||||
*
|
||||
* @param majorVersion the major version
|
||||
* @param minorVersion the minor version
|
||||
* @param minorVersion the minor version
|
||||
*/
|
||||
case class Version(majorVersion: Int, minorVersion: Int){
|
||||
|
||||
@@ -22,7 +22,7 @@ object AutoUpdate {
|
||||
|
||||
/**
|
||||
* Execute update/MAJOR_MINOR.sql to update schema to this version.
|
||||
* If corresponding SQL file does not exist, this method do nothing.
|
||||
* If corresponding SQL file does not exist, this method do nothing.
|
||||
*/
|
||||
def update(conn: Connection): Unit = {
|
||||
val sqlPath = "update/%d_%d.sql".format(majorVersion, minorVersion)
|
||||
@@ -40,7 +40,7 @@ object AutoUpdate {
|
||||
}
|
||||
|
||||
/**
|
||||
* MAJOR.MINOR
|
||||
* MAJOR.MINOR
|
||||
*/
|
||||
val versionString = "%d.%d".format(majorVersion, minorVersion)
|
||||
}
|
||||
@@ -49,6 +49,7 @@ object AutoUpdate {
|
||||
* The history of versions. A head of this sequence is the current BitBucket version.
|
||||
*/
|
||||
val versions = Seq(
|
||||
Version(1, 1),
|
||||
Version(1, 0)
|
||||
)
|
||||
|
||||
@@ -84,7 +85,7 @@ object AutoUpdate {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start H2 database and update schema automatically.
|
||||
* Start H2 database and update schema automatically.
|
||||
*/
|
||||
class AutoUpdateListener extends org.h2.server.web.DbStarter {
|
||||
import AutoUpdate._
|
||||
|
||||
@@ -25,8 +25,6 @@ class GitBucketLinkRender(context: app.Context, repository: service.RepositorySe
|
||||
enableWikiLink: Boolean) extends LinkRenderer {
|
||||
override def render(node: WikiLinkNode): Rendering = {
|
||||
if(enableWikiLink){
|
||||
super.render(node)
|
||||
} else {
|
||||
try {
|
||||
val text = node.getText
|
||||
val (label, page) = if(text.contains('|')){
|
||||
@@ -35,12 +33,14 @@ class GitBucketLinkRender(context: app.Context, repository: service.RepositorySe
|
||||
} else {
|
||||
(text, text)
|
||||
}
|
||||
val url = "%s/%s/%s/wiki/%s".format(context.path, repository.owner, repository.name,
|
||||
java.net.URLEncoder.encode(page.replace(' ', '-'), "UTF-8"))
|
||||
val url = repository.url.replaceFirst("/git/", "/").replaceFirst("\\.git$", "") +
|
||||
"/wiki/" + java.net.URLEncoder.encode(page.replace(' ', '-'), "UTF-8")
|
||||
new Rendering(url, label)
|
||||
} catch {
|
||||
case e: java.io.UnsupportedEncodingException => throw new IllegalStateException();
|
||||
}
|
||||
} else {
|
||||
super.render(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,8 +96,11 @@ class GitBucketHtmlSerializer(
|
||||
}
|
||||
|
||||
private def fixUrl(url: String): String = {
|
||||
if(!enableWikiLink || url.startsWith("http://") || url.startsWith("https://")) url
|
||||
else repository.url.replaceFirst("/git/", "/").replaceFirst("\\.git$", "") + "/wiki/_blob/" + url
|
||||
if(!enableWikiLink || url.startsWith("http://") || url.startsWith("https://")){
|
||||
url
|
||||
} else {
|
||||
repository.url.replaceFirst("/git/", "/").replaceFirst("\\.git$", "") + "/wiki/_blob/" + url
|
||||
}
|
||||
}
|
||||
|
||||
private def printAttribute(name: String, value: String) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
} else {
|
||||
<h3>Create your account</h3>
|
||||
}
|
||||
<form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{/register}" method="POST" validate="true">
|
||||
<form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{@path/register}" method="POST" validate="true">
|
||||
@if(account.isEmpty){
|
||||
<fieldset>
|
||||
<label for="userName"><strong>User name</strong></label>
|
||||
|
||||
@@ -105,13 +105,15 @@ $(function(){
|
||||
if($(this).data('selected') == true){
|
||||
$(this).css({
|
||||
'background-color': 'white',
|
||||
'color' : 'black'
|
||||
'color' : 'black',
|
||||
'font-weight' : 'normal'
|
||||
});
|
||||
$(this).data('selected', false);
|
||||
} else {
|
||||
$(this).css({
|
||||
'background-color': '#' + $(this).data('bgcolor'),
|
||||
'color' : '#' + $(this).data('fgcolor')
|
||||
'color' : '#' + $(this).data('fgcolor'),
|
||||
'font-weight' : 'bold'
|
||||
});
|
||||
$(this).data('selected', true);
|
||||
}
|
||||
|
||||
@@ -176,7 +176,9 @@
|
||||
<span class="pull-right muted">#@issue.issueId</span>
|
||||
<div class="small muted">
|
||||
Opened by <a href="@url(issue.openedUserName)" class="username">@issue.openedUserName</a> @datetime(issue.registeredDate)
|
||||
<i class="icon-comment"></i><a href="@url(repository)/issues/@issue.issueId" class="issue-comment-count">@commentCount @plural(commentCount, "comment")</a>
|
||||
@if(commentCount > 0){
|
||||
<i class="icon-comment"></i><a href="@url(repository)/issues/@issue.issueId" class="issue-comment-count">@commentCount @plural(commentCount, "comment")</a>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -57,7 +57,4 @@
|
||||
@body
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
$(function(){ prettyPrint(); });
|
||||
</script>
|
||||
</html>
|
||||
@@ -1,5 +1,11 @@
|
||||
$(function(){
|
||||
$.ajaxSetup({
|
||||
cache: false
|
||||
});
|
||||
|
||||
$('#repository-url').click(function(){
|
||||
this.select(0, this.value.length);
|
||||
});
|
||||
|
||||
prettyPrint();
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ function validate(e){
|
||||
|
||||
$.post(form.attr('action') + '/validate', $(e.target).serialize(), function(data){
|
||||
// clear all error messages
|
||||
$('.error-message').text('');
|
||||
$('.error').text('');
|
||||
|
||||
if($.isEmptyObject(data)){
|
||||
form.data('validated', true);
|
||||
|
||||
Reference in New Issue
Block a user