mirror of
				https://github.com/gitbucket/gitbucket.git
				synced 2025-10-31 18:46:28 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			disable-gi
			...
			quill
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8a9588f17f | ||
|  | 682f3a4c10 | ||
|  | dad29d93c2 | ||
|  | fc99de8a65 | ||
|  | bc4af8e7c1 | ||
|  | cb3a79c9b3 | ||
|  | b775ce157f | ||
|  | cfcd250914 | 
| @@ -38,6 +38,7 @@ libraryDependencies ++= Seq( | ||||
|   "com.mchange"               % "c3p0"                         % "0.9.5.2", | ||||
|   "com.typesafe"              % "config"                       % "1.3.0", | ||||
|   "com.typesafe.akka"        %% "akka-actor"                   % "2.3.14", | ||||
|   "io.getquill"              %% "quill-jdbc"                   % "0.4.1", | ||||
|   "fr.brouillard.oss.security.xhub" % "xhub4j-core"            % "1.0.0", | ||||
|   "com.enragedginger"        %% "akka-quartz-scheduler"        % "1.4.0-akka-2.3.x" exclude("c3p0","c3p0"), | ||||
|   "org.eclipse.jetty"         % "jetty-webapp"                 % JettyVersion     % "provided", | ||||
|   | ||||
							
								
								
									
										8
									
								
								src/main/resources/application.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/main/resources/application.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| db.dataSourceClassName="org.h2.jdbcx.JdbcDataSource" | ||||
| db.dataSource.url="jdbc:h2:~/.gitbucket/data;MVCC=true" | ||||
| db.dataSource.user="sa" | ||||
| db.dataSource.password="sa" | ||||
| #db.dataSource.cachePrepStmts=true | ||||
| #db.dataSource.prepStmtCacheSize=250 | ||||
| #db.dataSource.prepStmtCacheSqlLimit=2048 | ||||
| #db.connectionTimeout=30000 | ||||
| @@ -39,7 +39,7 @@ object ApiRepository{ | ||||
|       description = repository.description.getOrElse(""), | ||||
|       watchers    = 0, | ||||
|       forks       = forkedCount, | ||||
|       `private`   = repository.isPrivate, | ||||
|       `private`   = repository.`private`, | ||||
|       default_branch = repository.defaultBranch, | ||||
|       owner       = owner | ||||
|     )(urlIsHtmlUrl) | ||||
|   | ||||
| @@ -29,8 +29,8 @@ object ApiUser{ | ||||
|   def apply(user: Account): ApiUser = ApiUser( | ||||
|     login      = user.userName, | ||||
|     email      = user.mailAddress, | ||||
|     `type`     = if(user.isGroupAccount){ "Organization" }else{ "User" }, | ||||
|     site_admin = user.isAdmin, | ||||
|     `type`     = if(user.groupAccount){ "Organization" }else{ "User" }, | ||||
|     site_admin = user.administrator, | ||||
|     created_at = user.registeredDate | ||||
|   ) | ||||
| } | ||||
|   | ||||
| @@ -114,23 +114,23 @@ trait AccountControllerBase extends AccountManagementControllerBase { | ||||
|         // Public Activity | ||||
|         case "activity" => | ||||
|           gitbucket.core.account.html.activity(account, | ||||
|             if(account.isGroupAccount) Nil else getGroupsByUserName(userName), | ||||
|             if(account.groupAccount) Nil else getGroupsByUserName(userName), | ||||
|             getActivitiesByUser(userName, true)) | ||||
|  | ||||
|         // Members | ||||
|         case "members" if(account.isGroupAccount) => { | ||||
|         case "members" if(account.groupAccount) => { | ||||
|           val members = getGroupMembers(account.userName) | ||||
|           gitbucket.core.account.html.members(account, members.map(_.userName), | ||||
|             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.manager })) | ||||
|         } | ||||
|  | ||||
|         // Repositories | ||||
|         case _ => { | ||||
|           val members = getGroupMembers(account.userName) | ||||
|           gitbucket.core.account.html.repositories(account, | ||||
|             if(account.isGroupAccount) Nil else getGroupsByUserName(userName), | ||||
|             if(account.groupAccount) Nil else getGroupsByUserName(userName), | ||||
|             getVisibleRepositories(context.loginAccount, Some(userName)), | ||||
|             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.manager })) | ||||
|         } | ||||
|       } | ||||
|     } getOrElse NotFound | ||||
| @@ -190,7 +190,7 @@ trait AccountControllerBase extends AccountManagementControllerBase { | ||||
| //      removeUserRelatedData(userName) | ||||
|  | ||||
|       removeUserRelatedData(userName) | ||||
|       updateAccount(account.copy(isRemoved = true)) | ||||
|       updateAccount(account.copy(removed = true)) | ||||
|     } | ||||
|  | ||||
|     session.invalidate | ||||
| @@ -360,7 +360,7 @@ trait AccountControllerBase extends AccountManagementControllerBase { | ||||
|       case _: List[String] => | ||||
|         val managerPermissions = groups.map { group => | ||||
|           val members = getGroupMembers(group) | ||||
|           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.manager }) | ||||
|         } | ||||
|         helper.html.forkrepository( | ||||
|           repository, | ||||
| @@ -389,7 +389,7 @@ trait AccountControllerBase extends AccountManagementControllerBase { | ||||
|           repositoryName       = repository.name, | ||||
|           userName             = accountName, | ||||
|           description          = repository.repository.description, | ||||
|           isPrivate            = repository.repository.isPrivate, | ||||
|           isPrivate            = repository.repository.`private`, | ||||
|           originRepositoryName = Some(originRepositoryName), | ||||
|           originUserName       = Some(originUserName), | ||||
|           parentRepositoryName = Some(repository.name), | ||||
| @@ -398,7 +398,7 @@ trait AccountControllerBase extends AccountManagementControllerBase { | ||||
|  | ||||
|         // Add collaborators for group repository | ||||
|         val ownerAccount = getAccountByUserName(accountName).get | ||||
|         if(ownerAccount.isGroupAccount){ | ||||
|         if(ownerAccount.groupAccount){ | ||||
|           getGroupMembers(accountName).foreach { member => | ||||
|             addCollaborator(accountName, repository.name, member.userName) | ||||
|           } | ||||
|   | ||||
| @@ -50,7 +50,7 @@ abstract class ControllerBase extends ScalatraFilter | ||||
|       if(account == null){ | ||||
|         // Redirect to login form | ||||
|         httpResponse.sendRedirect(baseUrl + "/signin?redirect=" + StringUtil.urlEncode(path)) | ||||
|       } else if(account.isAdmin){ | ||||
|       } else if(account.administrator){ | ||||
|         // H2 Console (administrators only) | ||||
|         chain.doFilter(request, response) | ||||
|       } else { | ||||
|   | ||||
| @@ -110,7 +110,7 @@ trait IndexControllerBase extends ControllerBase { | ||||
|   get("/_user/proposals")(usersOnly { | ||||
|     contentType = formats("json") | ||||
|     org.json4s.jackson.Serialization.write( | ||||
|       Map("options" -> getAllUsers(false).filter(!_.isGroupAccount).map(_.userName).toArray) | ||||
|       Map("options" -> getAllUsers(false).filter(!_.groupAccount).map(_.userName).toArray) | ||||
|     ) | ||||
|   }) | ||||
|  | ||||
|   | ||||
| @@ -67,7 +67,7 @@ trait IssuesControllerBase extends ControllerBase { | ||||
|           _, | ||||
|           getComments(owner, name, issueId.toInt), | ||||
|           getIssueLabels(owner, name, issueId.toInt), | ||||
|           (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted, | ||||
|           (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted, | ||||
|           getMilestonesWithIssueCount(owner, name), | ||||
|           getLabels(owner, name), | ||||
|           hasWritePermission(owner, name, context.loginAccount), | ||||
| @@ -79,7 +79,7 @@ trait IssuesControllerBase extends ControllerBase { | ||||
|   get("/:owner/:repository/issues/new")(readableUsersOnly { repository => | ||||
|     defining(repository.owner, repository.name){ case (owner, name) => | ||||
|       html.create( | ||||
|         (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted, | ||||
|         (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted, | ||||
|           getMilestones(owner, name), | ||||
|           getLabels(owner, name), | ||||
|           hasWritePermission(owner, name, context.loginAccount), | ||||
| @@ -380,7 +380,7 @@ trait IssuesControllerBase extends ControllerBase { | ||||
|           "issues", | ||||
|           searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName), | ||||
|           page, | ||||
|           if(!getAccountByUserName(owner).exists(_.isGroupAccount)){ | ||||
|           if(!getAccountByUserName(owner).exists(_.groupAccount)){ | ||||
|             (getCollaborators(owner, repoName) :+ owner).sorted | ||||
|           } else { | ||||
|             getCollaborators(owner, repoName) | ||||
|   | ||||
| @@ -94,7 +94,7 @@ trait PullRequestsControllerBase extends ControllerBase { | ||||
|             (commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId)) | ||||
|               .sortWith((a, b) => a.registeredDate before b.registeredDate), | ||||
|             getIssueLabels(owner, name, issueId), | ||||
|             (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted, | ||||
|             (getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted, | ||||
|             getMilestonesWithIssueCount(owner, name), | ||||
|             getLabels(owner, name), | ||||
|             commits, | ||||
| @@ -370,7 +370,7 @@ trait PullRequestsControllerBase extends ControllerBase { | ||||
|               originRepository, | ||||
|               forkedRepository, | ||||
|               hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount), | ||||
|               (getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.isGroupAccount) Nil else List(originRepository.owner))).sorted, | ||||
|               (getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.groupAccount) Nil else List(originRepository.owner))).sorted, | ||||
|               getMilestones(originRepository.owner, originRepository.name), | ||||
|               getLabels(originRepository.owner, originRepository.name) | ||||
|             ) | ||||
| @@ -524,7 +524,7 @@ trait PullRequestsControllerBase extends ControllerBase { | ||||
|         "pulls", | ||||
|         searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName), | ||||
|         page, | ||||
|         if(!getAccountByUserName(owner).exists(_.isGroupAccount)){ | ||||
|         if(!getAccountByUserName(owner).exists(_.groupAccount)){ | ||||
|           (getCollaborators(owner, repoName) :+ owner).sorted | ||||
|         } else { | ||||
|           getCollaborators(owner, repoName) | ||||
|   | ||||
| @@ -87,7 +87,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { | ||||
|       repository.name, | ||||
|       form.description, | ||||
|       repository.repository.parentUserName.map { _ => | ||||
|         repository.repository.isPrivate | ||||
|         repository.repository.`private` | ||||
|       } getOrElse form.isPrivate | ||||
|     ) | ||||
|     // Change repository name | ||||
| @@ -148,7 +148,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { | ||||
|   get("/:owner/:repository/settings/collaborators")(ownerOnly { repository => | ||||
|     html.collaborators( | ||||
|       getCollaborators(repository.owner, repository.name), | ||||
|       getAccountByUserName(repository.owner).get.isGroupAccount, | ||||
|       getAccountByUserName(repository.owner).get.groupAccount, | ||||
|       repository) | ||||
|   }) | ||||
|  | ||||
| @@ -156,7 +156,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { | ||||
|    * Add the collaborator. | ||||
|    */ | ||||
|   post("/:owner/:repository/settings/collaborators/add", collaboratorForm)(ownerOnly { (form, repository) => | ||||
|     if(!getAccountByUserName(repository.owner).get.isGroupAccount){ | ||||
|     if(!getAccountByUserName(repository.owner).get.groupAccount){ | ||||
|       addCollaborator(repository.owner, repository.name, form.userName) | ||||
|     } | ||||
|     redirect(s"/${repository.owner}/${repository.name}/settings/collaborators") | ||||
| @@ -166,7 +166,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { | ||||
|    * Add the collaborator. | ||||
|    */ | ||||
|   get("/:owner/:repository/settings/collaborators/remove")(ownerOnly { repository => | ||||
|     if(!getAccountByUserName(repository.owner).get.isGroupAccount){ | ||||
|     if(!getAccountByUserName(repository.owner).get.groupAccount){ | ||||
|       removeCollaborator(repository.owner, repository.name, params("name")) | ||||
|     } | ||||
|     redirect(s"/${repository.owner}/${repository.name}/settings/collaborators") | ||||
| @@ -364,7 +364,7 @@ trait RepositorySettingsControllerBase extends ControllerBase { | ||||
|     override def validate(name: String, value: String, messages: Messages): Option[String] = | ||||
|       getAccountByUserName(value) match { | ||||
|         case None => Some("User does not exist.") | ||||
|         case Some(x) if(x.isGroupAccount) | ||||
|         case Some(x) if(x.groupAccount) | ||||
|                   => Some("User does not exist.") | ||||
|         case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName)) | ||||
|                   => Some("User can access this repository already.") | ||||
|   | ||||
| @@ -157,7 +157,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase { | ||||
|   get("/admin/users")(adminOnly { | ||||
|     val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false) | ||||
|     val users          = getAllUsers(includeRemoved) | ||||
|     val members        = users.collect { case account if(account.isGroupAccount) => | ||||
|     val members        = users.collect { case account if(account.groupAccount) => | ||||
|       account.userName -> getGroupMembers(account.userName).map(_.userName) | ||||
|     }.toMap | ||||
|  | ||||
| @@ -196,12 +196,12 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase { | ||||
|       } | ||||
|  | ||||
|       updateAccount(account.copy( | ||||
|         password     = form.password.map(sha1).getOrElse(account.password), | ||||
|         fullName     = form.fullName, | ||||
|         mailAddress  = form.mailAddress, | ||||
|         isAdmin      = form.isAdmin, | ||||
|         url          = form.url, | ||||
|         isRemoved    = form.isRemoved)) | ||||
|         password      = form.password.map(sha1).getOrElse(account.password), | ||||
|         fullName      = form.fullName, | ||||
|         mailAddress   = form.mailAddress, | ||||
|         administrator = form.isAdmin, | ||||
|         url           = form.url, | ||||
|         removed       = form.isRemoved)) | ||||
|  | ||||
|       updateImage(userName, form.fileId, form.clearImage) | ||||
|       redirect("/admin/users") | ||||
|   | ||||
| @@ -11,7 +11,7 @@ trait AccountComponent { self: Profile => | ||||
|     val fullName = column[String]("FULL_NAME") | ||||
|     val mailAddress = column[String]("MAIL_ADDRESS") | ||||
|     val password = column[String]("PASSWORD") | ||||
|     val isAdmin = column[Boolean]("ADMINISTRATOR") | ||||
|     val administrator = column[Boolean]("ADMINISTRATOR") | ||||
|     val url = column[String]("URL") | ||||
|     val registeredDate = column[java.util.Date]("REGISTERED_DATE") | ||||
|     val updatedDate = column[java.util.Date]("UPDATED_DATE") | ||||
| @@ -19,7 +19,7 @@ trait AccountComponent { self: Profile => | ||||
|     val image = column[String]("IMAGE") | ||||
|     val groupAccount = column[Boolean]("GROUP_ACCOUNT") | ||||
|     val removed = column[Boolean]("REMOVED") | ||||
|     def * = (userName, fullName, mailAddress, password, isAdmin, url.?, registeredDate, updatedDate, lastLoginDate.?, image.?, groupAccount, removed) <> (Account.tupled, Account.unapply) | ||||
|     def * = (userName, fullName, mailAddress, password, administrator, url.?, registeredDate, updatedDate, lastLoginDate.?, image.?, groupAccount, removed) <> (Account.tupled, Account.unapply) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -28,12 +28,12 @@ case class Account( | ||||
|   fullName: String, | ||||
|   mailAddress: String, | ||||
|   password: String, | ||||
|   isAdmin: Boolean, | ||||
|   administrator: Boolean, | ||||
|   url: Option[String], | ||||
|   registeredDate: java.util.Date, | ||||
|   updatedDate: java.util.Date, | ||||
|   lastLoginDate: Option[java.util.Date], | ||||
|   image: Option[String], | ||||
|   isGroupAccount: Boolean, | ||||
|   isRemoved: Boolean | ||||
|   groupAccount: Boolean, | ||||
|   removed: Boolean | ||||
| ) | ||||
|   | ||||
| @@ -8,13 +8,13 @@ trait GroupMemberComponent { self: Profile => | ||||
|   class GroupMembers(tag: Tag) extends Table[GroupMember](tag, "GROUP_MEMBER") { | ||||
|     val groupName = column[String]("GROUP_NAME", O PrimaryKey) | ||||
|     val userName = column[String]("USER_NAME", O PrimaryKey) | ||||
|     val isManager = column[Boolean]("MANAGER") | ||||
|     def * = (groupName, userName, isManager) <> (GroupMember.tupled, GroupMember.unapply) | ||||
|     val manager = column[Boolean]("MANAGER") | ||||
|     def * = (groupName, userName, manager) <> (GroupMember.tupled, GroupMember.unapply) | ||||
|   } | ||||
| } | ||||
|  | ||||
| case class GroupMember( | ||||
|   groupName: String, | ||||
|   userName: String, | ||||
|   isManager: Boolean | ||||
|   manager: Boolean | ||||
| ) | ||||
|   | ||||
| @@ -26,7 +26,7 @@ trait RepositoryComponent extends TemplateComponent { self: Profile => | ||||
| case class Repository( | ||||
|   userName: String, | ||||
|   repositoryName: String, | ||||
|   isPrivate: Boolean, | ||||
|   `private`: Boolean, | ||||
|   description: Option[String], | ||||
|   defaultBranch: String, | ||||
|   registeredDate: java.util.Date, | ||||
|   | ||||
| @@ -5,6 +5,8 @@ import profile.simple._ | ||||
|  | ||||
| import gitbucket.core.model.{Account, AccessToken} | ||||
| import gitbucket.core.util.StringUtil | ||||
| import gitbucket.core.servlet.Database._ | ||||
| import io.getquill._ | ||||
|  | ||||
| import scala.util.Random | ||||
|  | ||||
| @@ -27,28 +29,36 @@ trait AccessTokenService { | ||||
|     var hash: String = null | ||||
|     do{ | ||||
|       token = makeAccessTokenString | ||||
|       hash = tokenToHash(token) | ||||
|     }while(AccessTokens.filter(_.tokenHash === hash.bind).exists.run) | ||||
|       hash  = tokenToHash(token) | ||||
|     } while ( | ||||
|       db.run(quote { (hash: String) => query[AccessToken].filter(_.tokenHash == hash).nonEmpty })(hash).head | ||||
|     ) | ||||
|     val newToken = AccessToken( | ||||
|         userName = userName, | ||||
|         note = note, | ||||
|         tokenHash = hash) | ||||
|  | ||||
|     // TODO Remain Slick code | ||||
|     val tokenId = (AccessTokens returning AccessTokens.map(_.accessTokenId)) += newToken | ||||
|     (tokenId, token) | ||||
|   } | ||||
|  | ||||
|   def getAccountByAccessToken(token: String)(implicit s: Session): Option[Account] = | ||||
|     Accounts | ||||
|       .innerJoin(AccessTokens) | ||||
|       .filter{ case (ac, t) => (ac.userName === t.userName) && (t.tokenHash === tokenToHash(token).bind) && (ac.removed === false.bind) } | ||||
|       .map{ case (ac, t) => ac } | ||||
|       .firstOption | ||||
|   def getAccountByAccessToken(token: String): Option[Account] = | ||||
|     db.run(quote { (tokenHash: String) => | ||||
|         query[AccessToken].filter(_.tokenHash == tokenHash) | ||||
|           .join(query[Account]).on { (t, a) => t.userName == a.userName && a.registeredDate == false } | ||||
|           .map { case (t, a) => a } | ||||
|     })(tokenToHash(token)).headOption | ||||
|  | ||||
|   def getAccessTokens(userName: String)(implicit s: Session): List[AccessToken] = | ||||
|     AccessTokens.filter(_.userName === userName.bind).sortBy(_.accessTokenId.desc).list | ||||
|   def getAccessTokens(userName: String): List[AccessToken] = | ||||
|     db.run(quote { (userName: String) => | ||||
|       query[AccessToken].filter(_.userName == userName).sortBy(_.accessTokenId)(Ord.desc) | ||||
|     })(userName) | ||||
|  | ||||
|   def deleteAccessToken(userName: String, accessTokenId: Int)(implicit s: Session): Unit = | ||||
|     AccessTokens filter (t => t.userName === userName.bind && t.accessTokenId === accessTokenId) delete | ||||
|   def deleteAccessToken(userName: String, accessTokenId: Int): Unit = | ||||
|     db.run(quote { (userName: String, accessTokenId: Int) => | ||||
|       query[AccessToken].filter { t => t.userName == userName && t.accessTokenId == accessTokenId }.delete | ||||
|     })(List((userName, accessTokenId))) | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,20 +1,23 @@ | ||||
| package gitbucket.core.service | ||||
|  | ||||
| import gitbucket.core.model.{GroupMember, Account} | ||||
| import java.util.Date | ||||
|  | ||||
| import gitbucket.core.model.{GroupMember, Account, Collaborator, Repository} | ||||
| import gitbucket.core.model.Profile._ | ||||
| import gitbucket.core.util.{StringUtil, LDAPUtil} | ||||
| import gitbucket.core.service.SystemSettingsService.SystemSettings | ||||
| import profile.simple._ | ||||
| import StringUtil._ | ||||
| import org.slf4j.LoggerFactory | ||||
| // TODO Why is direct import required? | ||||
| import gitbucket.core.model.Profile.dateColumnType | ||||
|  | ||||
| import gitbucket.core.servlet.Database._ | ||||
| import io.getquill._ | ||||
|  | ||||
| trait AccountService { | ||||
|  | ||||
|   private val logger = LoggerFactory.getLogger(classOf[AccountService]) | ||||
|  | ||||
|   def authenticate(settings: SystemSettings, userName: String, password: String)(implicit s: Session): Option[Account] = | ||||
|   def authenticate(settings: SystemSettings, userName: String, password: String): Option[Account] = | ||||
|     if(settings.ldapAuthentication){ | ||||
|       ldapAuthentication(settings, userName, password) | ||||
|     } else { | ||||
| @@ -24,22 +27,21 @@ trait AccountService { | ||||
|   /** | ||||
|    * Authenticate by internal database. | ||||
|    */ | ||||
|   private def defaultAuthentication(userName: String, password: String)(implicit s: Session) = { | ||||
|   private def defaultAuthentication(userName: String, password: String) = { | ||||
|     getAccountByUserName(userName).collect { | ||||
|       case account if(!account.isGroupAccount && account.password == sha1(password)) => Some(account) | ||||
|       case account if(!account.groupAccount && account.password == sha1(password)) => Some(account) | ||||
|     } getOrElse None | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Authenticate by LDAP. | ||||
|    */ | ||||
|   private def ldapAuthentication(settings: SystemSettings, userName: String, password: String) | ||||
|                                 (implicit s: Session): Option[Account] = { | ||||
|   private def ldapAuthentication(settings: SystemSettings, userName: String, password: String): Option[Account] = { | ||||
|     LDAPUtil.authenticate(settings.ldap.get, userName, password) match { | ||||
|       case Right(ldapUserInfo) => { | ||||
|         // Create or update account by LDAP information | ||||
|         getAccountByUserName(ldapUserInfo.userName, true) match { | ||||
|           case Some(x) if(!x.isRemoved) => { | ||||
|           case Some(x) if(!x.removed) => { | ||||
|             if(settings.ldap.get.mailAttribute.getOrElse("").isEmpty) { | ||||
|               updateAccount(x.copy(fullName = ldapUserInfo.fullName)) | ||||
|             } else { | ||||
| @@ -47,16 +49,16 @@ trait AccountService { | ||||
|             } | ||||
|             getAccountByUserName(ldapUserInfo.userName) | ||||
|           } | ||||
|           case Some(x) if(x.isRemoved)  => { | ||||
|           case Some(x) if(x.removed)  => { | ||||
|             logger.info("LDAP Authentication Failed: Account is already registered but disabled.") | ||||
|             defaultAuthentication(userName, password) | ||||
|           } | ||||
|           case None => getAccountByMailAddress(ldapUserInfo.mailAddress, true) match { | ||||
|             case Some(x) if(!x.isRemoved) => { | ||||
|             case Some(x) if(!x.removed) => { | ||||
|               updateAccount(x.copy(fullName = ldapUserInfo.fullName)) | ||||
|               getAccountByUserName(ldapUserInfo.userName) | ||||
|             } | ||||
|             case Some(x) if(x.isRemoved)  => { | ||||
|             case Some(x) if(x.removed)  => { | ||||
|               logger.info("LDAP Authentication Failed: Account is already registered but disabled.") | ||||
|               defaultAuthentication(userName, password) | ||||
|             } | ||||
| @@ -74,113 +76,163 @@ trait AccountService { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def getAccountByUserName(userName: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] = | ||||
|     Accounts filter(t => (t.userName === userName.bind) && (t.removed === false.bind, !includeRemoved)) firstOption | ||||
|   def getAccountByUserName(userName: String, includeRemoved: Boolean = false): Option[Account] = { | ||||
|     db.run(quote { (userName: String, includeRemoved: Boolean) => | ||||
|       query[Account].filter { t => | ||||
|         if(includeRemoved){ | ||||
|           t.userName == userName | ||||
|         } else { | ||||
|           t.userName == userName && t.removed == false | ||||
|         } | ||||
|       } | ||||
|     })(userName, includeRemoved).headOption | ||||
|   } | ||||
|  | ||||
|   def getAccountsByUserNames(userNames: Set[String], knowns:Set[Account], includeRemoved: Boolean = false)(implicit s: Session): Map[String, Account] = { | ||||
|  | ||||
|   def getAccountsByUserNames(userNames: Set[String], knowns:Set[Account], includeRemoved: Boolean = false): Map[String, Account] = { | ||||
|     val map = knowns.map(a => a.userName -> a).toMap | ||||
|     val needs = userNames -- map.keySet | ||||
|     if(needs.isEmpty){ | ||||
|       map | ||||
|     }else{ | ||||
|       map ++ Accounts.filter(t => (t.userName inSetBind needs) && (t.removed === false.bind, !includeRemoved)).list.map(a => a.userName -> a).toMap | ||||
|     } else { | ||||
|       map ++ db.run(quote { (userNames: Set[String]) => | ||||
|           query[Account].filter { t => userNames.contains(t.userName) && t.removed == false } | ||||
|       })(userNames.toSet).map { a => a.userName -> a }.toMap | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] = | ||||
|     Accounts filter(t => (t.mailAddress.toLowerCase === mailAddress.toLowerCase.bind) && (t.removed === false.bind, !includeRemoved)) firstOption | ||||
|   def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false): Option[Account] = { | ||||
|     db.run(quote { (mailAddress: String, includeRemoved: Boolean) => | ||||
|       query[Account].filter { t => | ||||
|         if(includeRemoved){ | ||||
|           t.mailAddress.toLowerCase == mailAddress.toLowerCase | ||||
|         } else { | ||||
|           t.mailAddress.toLowerCase == mailAddress.toLowerCase && t.removed == false | ||||
|         } | ||||
|       } | ||||
|     })(mailAddress, includeRemoved).headOption | ||||
|   } | ||||
|  | ||||
|   def getAllUsers(includeRemoved: Boolean = true)(implicit s: Session): List[Account] = | ||||
|     if(includeRemoved){ | ||||
|       Accounts sortBy(_.userName) list | ||||
|     } else { | ||||
|       Accounts filter (_.removed === false.bind) sortBy(_.userName) list | ||||
|     } | ||||
|   def getAllUsers(includeRemoved: Boolean = true): List[Account] = { | ||||
|     db.run( | ||||
|       if(includeRemoved){ | ||||
|         quote { query[Account].sortBy(_.userName) } | ||||
|       } else { | ||||
|         quote { query[Account].filter(_.removed == false).sortBy(_.userName) } | ||||
|       } | ||||
|     ) | ||||
|   } | ||||
|  | ||||
|   def createAccount(userName: String, password: String, fullName: String, mailAddress: String, isAdmin: Boolean, url: Option[String]) | ||||
|                    (implicit s: Session): Unit = | ||||
|     Accounts insert Account( | ||||
|   def createAccount(userName: String, password: String, fullName: String, mailAddress: String, isAdmin: Boolean, url: Option[String]): Unit = { | ||||
|     db.run(quote { query[Account].insert })(Account( | ||||
|       userName       = userName, | ||||
|       password       = password, | ||||
|       fullName       = fullName, | ||||
|       mailAddress    = mailAddress, | ||||
|       isAdmin        = isAdmin, | ||||
|       administrator  = isAdmin, | ||||
|       url            = url, | ||||
|       registeredDate = currentDate, | ||||
|       updatedDate    = currentDate, | ||||
|       lastLoginDate  = None, | ||||
|       image          = None, | ||||
|       isGroupAccount = false, | ||||
|       isRemoved      = false) | ||||
|       groupAccount   = false, | ||||
|       removed        = false | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   def updateAccount(account: Account)(implicit s: Session): Unit = | ||||
|     Accounts | ||||
|       .filter { a =>  a.userName === account.userName.bind } | ||||
|       .map    { a => (a.password, a.fullName, a.mailAddress, a.isAdmin, a.url.?, a.registeredDate, a.updatedDate, a.lastLoginDate.?, a.removed) } | ||||
|       .update ( | ||||
|         account.password, | ||||
|         account.fullName, | ||||
|         account.mailAddress, | ||||
|         account.isAdmin, | ||||
|         account.url, | ||||
|         account.registeredDate, | ||||
|         currentDate, | ||||
|         account.lastLoginDate, | ||||
|         account.isRemoved) | ||||
|   def updateAccount(account: Account): Unit = { | ||||
|     db.run(quote { (userName: String, password: String, fullName: String, mailAddress: String, administrator: Boolean, | ||||
|                     url: Option[String], registeredDate: Date, updatedDate: Date, lastLoginDate: Option[Date], removed: Boolean) => | ||||
|       query[Account].filter(_.userName == userName).update( | ||||
|         _.password       -> password, | ||||
|         _.fullName       -> fullName, | ||||
|         _.mailAddress    -> mailAddress, | ||||
|         _.administrator  -> administrator, | ||||
|         _.url            -> url, | ||||
|         _.registeredDate -> registeredDate, | ||||
|         _.updatedDate    -> updatedDate, | ||||
|         _.lastLoginDate  -> lastLoginDate, | ||||
|         _.removed        -> removed | ||||
|       ) | ||||
|     })(( | ||||
|       account.userName, | ||||
|       account.password, | ||||
|       account.fullName, | ||||
|       account.mailAddress, | ||||
|       account.administrator, | ||||
|       account.url, | ||||
|       account.registeredDate, | ||||
|       currentDate, | ||||
|       account.lastLoginDate, | ||||
|       account.removed | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   def updateAvatarImage(userName: String, image: Option[String])(implicit s: Session): Unit = | ||||
|     Accounts.filter(_.userName === userName.bind).map(_.image.?).update(image) | ||||
|   def updateAvatarImage(userName: String, image: Option[String]): Unit = { | ||||
|     db.run(quote { (userName: String, image: Option[String]) => | ||||
|       query[Account].filter(_.userName == userName).update(_.image -> image) | ||||
|     })((userName, image)) | ||||
|   } | ||||
|  | ||||
|   def updateLastLoginDate(userName: String)(implicit s: Session): Unit = | ||||
|     Accounts.filter(_.userName === userName.bind).map(_.lastLoginDate).update(currentDate) | ||||
|   def updateLastLoginDate(userName: String): Unit = { | ||||
|     db.run(quote { (userName: String, lastLoginDate: Option[Date]) => | ||||
|       query[Account].filter(_.userName == userName).update(_.lastLoginDate -> lastLoginDate) | ||||
|     })((userName, Some(currentDate))) | ||||
|   } | ||||
|  | ||||
|   def createGroup(groupName: String, url: Option[String])(implicit s: Session): Unit = | ||||
|     Accounts insert Account( | ||||
|   def createGroup(groupName: String, url: Option[String]): Unit = { | ||||
|     db.run( quote { query[Account].insert })(List(Account( | ||||
|       userName       = groupName, | ||||
|       password       = "", | ||||
|       fullName       = groupName, | ||||
|       mailAddress    = groupName + "@devnull", | ||||
|       isAdmin        = false, | ||||
|       administrator  = false, | ||||
|       url            = url, | ||||
|       registeredDate = currentDate, | ||||
|       updatedDate    = currentDate, | ||||
|       lastLoginDate  = None, | ||||
|       image          = None, | ||||
|       isGroupAccount = true, | ||||
|       isRemoved      = false) | ||||
|       groupAccount  = true, | ||||
|       removed       = false | ||||
|     ))) | ||||
|   } | ||||
|  | ||||
|   def updateGroup(groupName: String, url: Option[String], removed: Boolean)(implicit s: Session): Unit = | ||||
|     Accounts.filter(_.userName === groupName.bind).map(t => t.url.? -> t.removed).update(url, removed) | ||||
|   def updateGroup(groupName: String, url: Option[String], removed: Boolean): Unit = { | ||||
|     db.run(quote { (groupName: String, url: Option[String], removed: Boolean) => | ||||
|       query[Account].filter(_.userName == groupName).update(_.url -> url, _.removed -> removed) | ||||
|     })(List((groupName, url, removed))) | ||||
|   } | ||||
|  | ||||
|   def updateGroupMembers(groupName: String, members: List[(String, Boolean)]): Unit = { | ||||
|     db.run(quote { (groupName: String) => query[GroupMember].filter(_.groupName == groupName).delete })(groupName) | ||||
|  | ||||
|   def updateGroupMembers(groupName: String, members: List[(String, Boolean)])(implicit s: Session): Unit = { | ||||
|     GroupMembers.filter(_.groupName === groupName.bind).delete | ||||
|     members.foreach { case (userName, isManager) => | ||||
|       GroupMembers insert GroupMember (groupName, userName, isManager) | ||||
|       db.run(quote { query[GroupMember].insert })(GroupMember(groupName, userName, isManager)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   def getGroupMembers(groupName: String)(implicit s: Session): List[GroupMember] = | ||||
|     GroupMembers | ||||
|       .filter(_.groupName === groupName.bind) | ||||
|       .sortBy(_.userName) | ||||
|       .list | ||||
|  | ||||
|   def getGroupsByUserName(userName: String)(implicit s: Session): List[String] = | ||||
|     GroupMembers | ||||
|       .filter(_.userName === userName.bind) | ||||
|       .sortBy(_.groupName) | ||||
|       .map(_.groupName) | ||||
|       .list | ||||
|  | ||||
|   def removeUserRelatedData(userName: String)(implicit s: Session): Unit = { | ||||
|     GroupMembers.filter(_.userName === userName.bind).delete | ||||
|     Collaborators.filter(_.collaboratorName === userName.bind).delete | ||||
|     Repositories.filter(_.userName === userName.bind).delete | ||||
|   def getGroupMembers(groupName: String): List[GroupMember] = { | ||||
|     db.run(quote { (groupName: String) => | ||||
|       query[GroupMember].filter(_.groupName == groupName).sortBy(_.userName) | ||||
|     })(groupName) | ||||
|   } | ||||
|  | ||||
|   def getGroupNames(userName: String)(implicit s: Session): List[String] = { | ||||
|     List(userName) ++ | ||||
|       Collaborators.filter(_.collaboratorName === userName.bind).sortBy(_.userName).map(_.userName).list | ||||
|   def getGroupsByUserName(userName: String): List[String] = { | ||||
|     db.run(quote { (userName: String) => | ||||
|       query[GroupMember].filter(_.userName == userName).sortBy(_.groupName).map(_.groupName) | ||||
|     })(userName) | ||||
|   } | ||||
|  | ||||
|   def removeUserRelatedData(userName: String): Unit = { | ||||
|     db.run(quote { (userName: String) => query[GroupMember].filter(_.userName == userName).delete })(userName) | ||||
|     db.run(quote { (userName: String) => query[Collaborator].filter(_.collaboratorName == userName).delete })(userName) | ||||
|     db.run(quote { (userName: String) => query[Repository].filter(_.userName == userName).delete })(userName) | ||||
|   } | ||||
|  | ||||
|   def getGroupNames(userName: String): List[String] = { | ||||
|     List(userName) ++ db.run(quote { (userName: String) => | ||||
|       query[Collaborator].filter(_.collaboratorName == userName).sortBy(_.userName).map(_.userName) | ||||
|     })(userName) | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,194 +1,180 @@ | ||||
| package gitbucket.core.service | ||||
|  | ||||
| import gitbucket.core.model.Activity | ||||
| import gitbucket.core.model._ | ||||
| import gitbucket.core.model.Profile._ | ||||
| import gitbucket.core.util.JGitUtil | ||||
| import profile.simple._ | ||||
|  | ||||
| import gitbucket.core.servlet.Database._ | ||||
| import io.getquill._ | ||||
|  | ||||
| trait ActivityService { | ||||
|  | ||||
|   def deleteOldActivities(limit: Int)(implicit s: Session): Int = { | ||||
|     Activities.map(_.activityId).sortBy(_ desc).drop(limit).firstOption.map { id => | ||||
|       Activities.filter(_.activityId <= id.bind).delete | ||||
|   def deleteOldActivities(limit: Int): Int = | ||||
|     db.run (quote { (limit: Int) => | ||||
|       query[Activity].map(_.activityId).sortBy(x => x)(Ord.desc).drop(limit) | ||||
|     })(limit).headOption.map { activityId => | ||||
|       db.run ( | ||||
|         quote { (activityId: Int) => query[Activity].filter(_.activityId <= activityId).delete } | ||||
|       )(activityId) | ||||
|     } getOrElse 0 | ||||
|   } | ||||
|  | ||||
|   def getActivitiesByUser(activityUserName: String, isPublic: Boolean)(implicit s: Session): List[Activity] = | ||||
|     Activities | ||||
|       .innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName)) | ||||
|       .filter { case (t1, t2) => | ||||
|         if(isPublic){ | ||||
|           (t1.activityUserName === activityUserName.bind) && (t2.isPrivate === false.bind) | ||||
|         } else { | ||||
|           (t1.activityUserName === activityUserName.bind) | ||||
|   def getActivitiesByUser(activityUserName: String, isPublic: Boolean): List[Activity] = | ||||
|     db.run(quote { (activityUserName: String, isPublic: Boolean) => | ||||
|       query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName) | ||||
|         .filter { case (a, r) => | ||||
|           if(isPublic){ | ||||
|             a.activityUserName == activityUserName | ||||
|           } else { | ||||
|             a.activityUserName == activityUserName && r.`private` == false | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       .sortBy { case (t1, t2) => t1.activityId desc } | ||||
|       .map    { case (t1, t2) => t1 } | ||||
|       .take(30) | ||||
|       .list | ||||
|         .sortBy { case (a, r) => a.activityId }(Ord.desc) | ||||
|         .map    { case (a, r) => a } | ||||
|         .take(30) | ||||
|     })(activityUserName, isPublic) | ||||
|  | ||||
|   def getRecentActivities()(implicit s: Session): List[Activity] = | ||||
|     Activities | ||||
|       .innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName)) | ||||
|       .filter { case (t1, t2) =>  t2.isPrivate === false.bind } | ||||
|       .sortBy { case (t1, t2) => t1.activityId desc } | ||||
|       .map    { case (t1, t2) => t1 } | ||||
|       .take(30) | ||||
|       .list | ||||
|   def getRecentActivities(): List[Activity] = | ||||
|     db.run(quote { | ||||
|       query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName) | ||||
|         .filter { case (a, r) => r.`private` == false} | ||||
|         .sortBy { case (a, r) => a.activityId }(Ord.desc) | ||||
|         .map    { case (a, r) => a } | ||||
|         .take(30) | ||||
|     }) | ||||
|  | ||||
|   def getRecentActivitiesByOwners(owners : Set[String])(implicit s: Session): List[Activity] = | ||||
|     Activities | ||||
|       .innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName)) | ||||
|       .filter { case (t1, t2) => (t2.isPrivate === false.bind) || (t2.userName inSetBind owners) } | ||||
|       .sortBy { case (t1, t2) => t1.activityId desc } | ||||
|       .map    { case (t1, t2) => t1 } | ||||
|       .take(30) | ||||
|       .list | ||||
|   def getRecentActivitiesByOwners(owners : Set[String]): List[Activity] = | ||||
|     db.run(quote { (owners: Set[String]) => | ||||
|       query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName) | ||||
|         .filter { case (a, r) => r.`private` == false || owners.contains(r.userName) } | ||||
|         .sortBy { case (a, r) => a.activityId }(Ord.desc) | ||||
|         .map    { case (a, r) => a } | ||||
|         .take(30) | ||||
|     })(owners) | ||||
|  | ||||
|   def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String) | ||||
|                                     (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "create_repository", | ||||
|       s"[user:${activityUserName}] created [repo:${userName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordCreateIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String) | ||||
|                                (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCreateIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "open_issue", | ||||
|       s"[user:${activityUserName}] opened issue [issue:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(title),  | ||||
|       currentDate) | ||||
|       Some(title)) | ||||
|  | ||||
|   def recordCloseIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String) | ||||
|                               (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCloseIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "close_issue", | ||||
|       s"[user:${activityUserName}] closed issue [issue:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(title), | ||||
|       currentDate) | ||||
|       Some(title)) | ||||
|  | ||||
|   def recordClosePullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String) | ||||
|                                     (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordClosePullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "close_issue", | ||||
|       s"[user:${activityUserName}] closed pull request [pullreq:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(title), | ||||
|       currentDate) | ||||
|       Some(title)) | ||||
|  | ||||
|   def recordReopenIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String) | ||||
|                                (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordReopenIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "reopen_issue", | ||||
|       s"[user:${activityUserName}] reopened issue [issue:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(title), | ||||
|       currentDate) | ||||
|       Some(title)) | ||||
|  | ||||
|   def recordCommentIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String) | ||||
|                                 (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCommentIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "comment_issue", | ||||
|       s"[user:${activityUserName}] commented on issue [issue:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(cut(comment, 200)), | ||||
|       currentDate) | ||||
|       Some(cut(comment, 200))) | ||||
|  | ||||
|   def recordCommentPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String) | ||||
|                                       (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCommentPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "comment_issue", | ||||
|       s"[user:${activityUserName}] commented on pull request [pullreq:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(cut(comment, 200)), | ||||
|       currentDate) | ||||
|       Some(cut(comment, 200))) | ||||
|  | ||||
|   def recordCommentCommitActivity(userName: String, repositoryName: String, activityUserName: String, commitId: String, comment: String) | ||||
|                                  (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCommentCommitActivity(userName: String, repositoryName: String, activityUserName: String, commitId: String, comment: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "comment_commit", | ||||
|       s"[user:${activityUserName}] commented on commit [commit:${userName}/${repositoryName}@${commitId}]", | ||||
|       Some(cut(comment, 200)), | ||||
|       currentDate | ||||
|     ) | ||||
|       Some(cut(comment, 200))) | ||||
|  | ||||
|   def recordCreateWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String) | ||||
|                                   (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCreateWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "create_wiki", | ||||
|       s"[user:${activityUserName}] created the [repo:${userName}/${repositoryName}] wiki", | ||||
|       Some(pageName), | ||||
|       currentDate) | ||||
|       Some(pageName)) | ||||
|  | ||||
|   def recordEditWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String, commitId: String) | ||||
|                                 (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordEditWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String, commitId: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "edit_wiki", | ||||
|       s"[user:${activityUserName}] edited the [repo:${userName}/${repositoryName}] wiki", | ||||
|       Some(pageName + ":" + commitId), | ||||
|       currentDate) | ||||
|       Some(pageName + ":" + commitId)) | ||||
|  | ||||
|   def recordPushActivity(userName: String, repositoryName: String, activityUserName: String, | ||||
|       branchName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|       branchName: String, commits: List[JGitUtil.CommitInfo]): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "push", | ||||
|       s"[user:${activityUserName}] pushed to [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]", | ||||
|       Some(commits.map { commit => commit.id + ":" + commit.shortMessage }.mkString("\n")), | ||||
|       currentDate) | ||||
|       Some(commits.map { commit => commit.id + ":" + commit.shortMessage }.mkString("\n"))) | ||||
|  | ||||
|   def recordCreateTagActivity(userName: String, repositoryName: String, activityUserName: String,  | ||||
|       tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|       tagName: String, commits: List[JGitUtil.CommitInfo]): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "create_tag", | ||||
|       s"[user:${activityUserName}] created tag [tag:${userName}/${repositoryName}#${tagName}] at [repo:${userName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordDeleteTagActivity(userName: String, repositoryName: String, activityUserName: String, | ||||
|                               tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|                               tagName: String, commits: List[JGitUtil.CommitInfo]): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "delete_tag", | ||||
|       s"[user:${activityUserName}] deleted tag ${tagName} at [repo:${userName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordCreateBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String) | ||||
|                                 (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordCreateBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "create_branch", | ||||
|       s"[user:${activityUserName}] created branch [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordDeleteBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String) | ||||
|                                 (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordDeleteBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "delete_branch", | ||||
|       s"[user:${activityUserName}] deleted branch ${branchName} at [repo:${userName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String)(implicit s: Session): Unit =  | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "fork", | ||||
|       s"[user:${activityUserName}] forked [repo:${userName}/${repositoryName}] to [repo:${forkedUserName}/${repositoryName}]", | ||||
|       None, | ||||
|       currentDate) | ||||
|       None) | ||||
|  | ||||
|   def recordPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String) | ||||
|                                (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "open_pullreq", | ||||
|       s"[user:${activityUserName}] opened pull request [pullreq:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(title), | ||||
|       currentDate) | ||||
|       Some(title)) | ||||
|  | ||||
|   def recordMergeActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, message: String) | ||||
|                          (implicit s: Session): Unit = | ||||
|     Activities insert Activity(userName, repositoryName, activityUserName, | ||||
|   def recordMergeActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, message: String): Unit = | ||||
|     insertActivity(userName, repositoryName, activityUserName, | ||||
|       "merge_pullreq", | ||||
|       s"[user:${activityUserName}] merged pull request [pullreq:${userName}/${repositoryName}#${issueId}]", | ||||
|       Some(message), | ||||
|       currentDate) | ||||
|       Some(message)) | ||||
|  | ||||
|   private def insertActivity(userName: String, repositoryName: String, activityUserName: String, activityType: String, | ||||
|                              message: String, additionalInfo: Option[String]): Unit = { | ||||
|     db.run(quote { query[Activity].insert })(Activity( | ||||
|       userName         = userName, | ||||
|       repositoryName   = repositoryName, | ||||
|       activityUserName = activityUserName, | ||||
|       activityType     = activityType, | ||||
|       message          = message, | ||||
|       additionalInfo   = additionalInfo, | ||||
|       activityDate     = currentDate | ||||
|     )) | ||||
|   } | ||||
|  | ||||
|   private def cut(value: String, length: Int): String = | ||||
|     if(value.length > length) value.substring(0, length) + "..." else value | ||||
|   | ||||
| @@ -1,35 +1,34 @@ | ||||
| package gitbucket.core.service | ||||
|  | ||||
| import gitbucket.core.model.CommitComment | ||||
| import gitbucket.core.util.{StringUtil, Implicits} | ||||
|  | ||||
| import scala.slick.jdbc.{StaticQuery => Q} | ||||
| import Q.interpolation | ||||
| import gitbucket.core.model.Profile._ | ||||
| import profile.simple._ | ||||
| import Implicits._ | ||||
| import StringUtil._ | ||||
|  | ||||
| import gitbucket.core.servlet.Database._ | ||||
| import io.getquill._ | ||||
|  | ||||
|  | ||||
| trait CommitsService { | ||||
|  | ||||
|   def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean)(implicit s: Session) = | ||||
|     CommitComments filter { | ||||
|       t => t.byCommit(owner, repository, commitId) && (t.issueId.isEmpty || includePullRequest) | ||||
|     } list | ||||
|   def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean) = | ||||
|     db.run(quote { (owner: String, repository: String, commitId: String, includePullRequest: Boolean) => | ||||
|       query[CommitComment].filter { t => | ||||
|         t.userName == owner && t.repositoryName == repository && t.commitId == commitId && (t.issueId.isEmpty || includePullRequest) | ||||
|       } | ||||
|     })(owner, repository, commitId, includePullRequest) | ||||
|  | ||||
|   def getCommitComment(owner: String, repository: String, commentId: String)(implicit s: Session) = | ||||
|   def getCommitComment(owner: String, repository: String, commentId: String) = | ||||
|     if (commentId forall (_.isDigit)) | ||||
|       CommitComments filter { t => | ||||
|         t.byPrimaryKey(commentId.toInt) && t.byRepository(owner, repository) | ||||
|       } firstOption | ||||
|       db.run(quote { (owner: String, repository: String, commentId: Int) => | ||||
|         query[CommitComment].filter(t => t.userName == owner && t.repositoryName == repository && t.commentId == commentId) | ||||
|       })(owner, repository, commentId.toInt).headOption | ||||
|     else | ||||
|       None | ||||
|  | ||||
|   def createCommitComment(owner: String, repository: String, commitId: String, loginUser: String, | ||||
|                           content: String, fileName: Option[String], oldLine: Option[Int], newLine: Option[Int], | ||||
|                           issueId: Option[Int])(implicit s: Session): Int = | ||||
|     CommitComments.autoInc insert CommitComment( | ||||
|     CommitComments.autoInc insert CommitComment( // TODO Remain Slick code | ||||
|       userName          = owner, | ||||
|       repositoryName    = repository, | ||||
|       commitId          = commitId, | ||||
| @@ -42,13 +41,12 @@ trait CommitsService { | ||||
|       updatedDate       = currentDate, | ||||
|       issueId           = issueId) | ||||
|  | ||||
|   def updateCommitComment(commentId: Int, content: String)(implicit s: Session) = | ||||
|     CommitComments | ||||
|       .filter (_.byPrimaryKey(commentId)) | ||||
|       .map { t => | ||||
|       t.content -> t.updatedDate | ||||
|     }.update (content, currentDate) | ||||
|   def updateCommitComment(commentId: Int, content: String) = | ||||
|     db.run(quote { (commentId: Int, content: String, updatedDate: java.util.Date) => | ||||
|       query[CommitComment].filter(_.commentId == commentId).update(_.content -> content, _.updatedDate -> updatedDate) | ||||
|     })(commentId, content, currentDate) | ||||
|  | ||||
|   def deleteCommitComment(commentId: Int) = | ||||
|     db.run(quote { (commentId: Int) => query[CommitComment].filter(_.commentId == commentId).delete })(commentId) | ||||
|  | ||||
|   def deleteCommitComment(commentId: Int)(implicit s: Session) = | ||||
|     CommitComments filter (_.byPrimaryKey(commentId)) delete | ||||
| } | ||||
|   | ||||
| @@ -76,7 +76,7 @@ object ProtectedBranchService { | ||||
|     includeAdministrators: Boolean) extends AccountService with CommitStatusService { | ||||
|  | ||||
|     def isAdministrator(pusher: String)(implicit session: Session): Boolean = | ||||
|       pusher == owner || getGroupMembers(owner).filter(gm => gm.userName == pusher && gm.isManager).nonEmpty | ||||
|       pusher == owner || getGroupMembers(owner).filter(gm => gm.userName == pusher && gm.manager).nonEmpty | ||||
|  | ||||
|     /** | ||||
|      * Can't be force pushed | ||||
|   | ||||
| @@ -22,7 +22,7 @@ trait RepositoryCreationService { | ||||
|     insertRepository(name, owner, description, isPrivate) | ||||
|  | ||||
|     // Add collaborators for group repository | ||||
|     if(ownerAccount.isGroupAccount){ | ||||
|     if(ownerAccount.groupAccount){ | ||||
|       getGroupMembers(owner).foreach { member => | ||||
|         addCollaborator(owner, name, member.userName) | ||||
|       } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ trait RepositoryService { self: AccountService => | ||||
|       Repository( | ||||
|         userName             = userName, | ||||
|         repositoryName       = repositoryName, | ||||
|         isPrivate            = isPrivate, | ||||
|         `private`            = isPrivate, | ||||
|         description          = description, | ||||
|         defaultBranch        = "master", | ||||
|         registeredDate       = currentDate, | ||||
| @@ -115,7 +115,7 @@ trait RepositoryService { self: AccountService => | ||||
|           repositoryName = newRepositoryName | ||||
|         )) :_*) | ||||
|  | ||||
|         if(account.isGroupAccount){ | ||||
|         if(account.groupAccount){ | ||||
|           Collaborators.insertAll(getGroupMembers(newUserName).map(m => Collaborator(newUserName, newRepositoryName, m.userName)) :_*) | ||||
|         } else { | ||||
|           Collaborators.insertAll(collaborators.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*) | ||||
| @@ -270,9 +270,9 @@ trait RepositoryService { self: AccountService => | ||||
|                             (implicit s: Session): List[RepositoryInfo] = { | ||||
|     (loginAccount match { | ||||
|       // for Administrators | ||||
|       case Some(x) if(x.isAdmin) => Repositories | ||||
|       case Some(x) if(x.administrator) => Repositories | ||||
|       // for Normal Users | ||||
|       case Some(x) if(!x.isAdmin) => | ||||
|       case Some(x) if(!x.administrator) => | ||||
|         Repositories filter { t => (t.isPrivate === false.bind) || (t.userName === x.userName) || | ||||
|           (Collaborators.filter { t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName === x.userName.bind)} exists) | ||||
|         } | ||||
| @@ -297,8 +297,8 @@ trait RepositoryService { self: AccountService => | ||||
|   } | ||||
|  | ||||
|   private def getRepositoryManagers(userName: String)(implicit s: Session): Seq[String] = | ||||
|     if(getAccountByUserName(userName).exists(_.isGroupAccount)){ | ||||
|       getGroupMembers(userName).collect { case x if(x.isManager) => x.userName } | ||||
|     if(getAccountByUserName(userName).exists(_.groupAccount)){ | ||||
|       getGroupMembers(userName).collect { case x if(x.manager) => x.userName } | ||||
|     } else { | ||||
|       Seq(userName) | ||||
|     } | ||||
| @@ -365,7 +365,7 @@ trait RepositoryService { self: AccountService => | ||||
|  | ||||
|   def hasWritePermission(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = { | ||||
|     loginAccount match { | ||||
|       case Some(a) if(a.isAdmin) => true | ||||
|       case Some(a) if(a.administrator) => true | ||||
|       case Some(a) if(a.userName == owner) => true | ||||
|       case Some(a) if(getCollaborators(owner, repository).contains(a.userName)) => true | ||||
|       case _ => false | ||||
|   | ||||
| @@ -76,14 +76,14 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou | ||||
|       case Array(_, repositoryOwner, repositoryName, _*) => | ||||
|         getRepository(repositoryOwner, repositoryName.replaceFirst("\\.wiki\\.git$|\\.git$", "")) match { | ||||
|           case Some(repository) => { | ||||
|             if(!isUpdating && !repository.repository.isPrivate && settings.allowAnonymousAccess){ | ||||
|             if(!isUpdating && !repository.repository.`private` && settings.allowAnonymousAccess){ | ||||
|               chain.doFilter(request, response) | ||||
|             } else { | ||||
|               val passed = for { | ||||
|                 auth <- Option(request.getHeader("Authorization")) | ||||
|                 Array(username, password) = decodeAuthHeader(auth).split(":", 2) | ||||
|                 account <- authenticate(settings, username, password) | ||||
|               } yield if(isUpdating || repository.repository.isPrivate){ | ||||
|               } yield if(isUpdating || repository.repository.`private`){ | ||||
|                   if(hasWritePermission(repository.owner, repository.name, Some(account))){ | ||||
|                     request.setAttribute(Keys.Request.UserName, account.userName) | ||||
|                     true | ||||
|   | ||||
| @@ -4,10 +4,14 @@ import javax.servlet._ | ||||
| import javax.servlet.http.HttpServletRequest | ||||
| import com.mchange.v2.c3p0.ComboPooledDataSource | ||||
| import gitbucket.core.util.DatabaseConfig | ||||
| import io.getquill._ | ||||
| import io.getquill.naming.SnakeCase | ||||
| import io.getquill.sources.sql.idiom.H2Dialect | ||||
| import org.scalatra.ScalatraBase | ||||
| import org.slf4j.LoggerFactory | ||||
| import slick.jdbc.JdbcBackend.{Database => SlickDatabase, Session} | ||||
| import gitbucket.core.util.Keys | ||||
| import Database._ | ||||
|  | ||||
| /** | ||||
|  * Controls the transaction with the open session in view pattern. | ||||
| @@ -25,17 +29,20 @@ class TransactionFilter extends Filter { | ||||
|       // assets don't need transaction | ||||
|       chain.doFilter(req, res) | ||||
|     } else { | ||||
|       Database() withTransaction { session => | ||||
|         // Register Scalatra error callback to rollback transaction | ||||
|         ScalatraBase.onFailure { _ => | ||||
|           logger.debug("Rolled back transaction") | ||||
|           session.rollback() | ||||
|         }(req.asInstanceOf[HttpServletRequest]) | ||||
|       db.transaction { | ||||
|         // TODO Delete after moving to quill | ||||
|         Database() withTransaction { session => | ||||
|           // Register Scalatra error callback to rollback transaction | ||||
|           ScalatraBase.onFailure { _ => | ||||
|             logger.debug("Rolled back transaction") | ||||
|             session.rollback() | ||||
|           }(req.asInstanceOf[HttpServletRequest]) | ||||
|  | ||||
|         logger.debug("begin transaction") | ||||
|         req.setAttribute(Keys.Request.DBSession, session) | ||||
|         chain.doFilter(req, res) | ||||
|         logger.debug("end transaction") | ||||
|           logger.debug("begin transaction") | ||||
|           req.setAttribute(Keys.Request.DBSession, session) | ||||
|           chain.doFilter(req, res) | ||||
|           logger.debug("end transaction") | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| @@ -46,6 +53,9 @@ object Database { | ||||
|  | ||||
|   private val logger = LoggerFactory.getLogger(Database.getClass) | ||||
|  | ||||
|   lazy val db = source(new JdbcSourceConfig[H2Dialect, SnakeCase]("db")) | ||||
|  | ||||
|   // TODO Delete after moving to quill | ||||
|   private val dataSource: ComboPooledDataSource = { | ||||
|     val ds = new ComboPooledDataSource | ||||
|     ds.setDriverClass(DatabaseConfig.driver) | ||||
| @@ -56,15 +66,19 @@ object Database { | ||||
|     ds | ||||
|   } | ||||
|  | ||||
|   private val db: SlickDatabase = { | ||||
|   // TODO Delete after moving to quill | ||||
|   private val slickDatabase: SlickDatabase = { | ||||
|     SlickDatabase.forDataSource(dataSource) | ||||
|   } | ||||
|  | ||||
|   def apply(): SlickDatabase = db | ||||
|   // TODO Delete after moving to quill | ||||
|   def apply(): SlickDatabase = slickDatabase | ||||
|  | ||||
|   // TODO Delete after moving to quill | ||||
|   def getSession(req: ServletRequest): Session = | ||||
|     req.getAttribute(Keys.Request.DBSession).asInstanceOf[Session] | ||||
|  | ||||
|   // TODO Delete after moving to quill | ||||
|   def closeDataSource(): Unit = dataSource.close | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -92,7 +92,7 @@ class DefaultGitUploadPack(owner: String, repoName: String) extends DefaultGitCo | ||||
|  | ||||
|   override protected def runTask(user: String)(implicit session: Session): Unit = { | ||||
|     getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).foreach { repositoryInfo => | ||||
|       if(!repositoryInfo.repository.isPrivate || isWritableUser(user, repositoryInfo)){ | ||||
|       if(!repositoryInfo.repository.`private` || isWritableUser(user, repositoryInfo)){ | ||||
|         using(Git.open(getRepositoryDir(owner, repoName))) { git => | ||||
|           val repository = git.getRepository | ||||
|           val upload = new UploadPack(repository) | ||||
|   | ||||
| @@ -17,7 +17,7 @@ trait OneselfAuthenticator { self: ControllerBase => | ||||
|     { | ||||
|       defining(request.paths){ paths => | ||||
|         context.loginAccount match { | ||||
|           case Some(x) if(x.isAdmin) => action | ||||
|           case Some(x) if(x.administrator) => action | ||||
|           case Some(x) if(paths(0) == x.userName) => action | ||||
|           case _ => Unauthorized() | ||||
|         } | ||||
| @@ -38,10 +38,10 @@ trait OwnerAuthenticator { self: ControllerBase with RepositoryService with Acco | ||||
|       defining(request.paths){ paths => | ||||
|         getRepository(paths(0), paths(1)).map { repository => | ||||
|           context.loginAccount match { | ||||
|             case Some(x) if(x.isAdmin) => action(repository) | ||||
|             case Some(x) if(x.administrator) => action(repository) | ||||
|             case Some(x) if(repository.owner == x.userName) => action(repository) | ||||
|             case Some(x) if(getGroupMembers(repository.owner).exists { member => | ||||
|               member.userName == x.userName && member.isManager == true | ||||
|               member.userName == x.userName && member.manager == true | ||||
|             }) => action(repository) | ||||
|             case _ => Unauthorized() | ||||
|           } | ||||
| @@ -78,7 +78,7 @@ trait AdminAuthenticator { self: ControllerBase => | ||||
|   private def authenticate(action: => Any) = { | ||||
|     { | ||||
|       context.loginAccount match { | ||||
|         case Some(x) if(x.isAdmin) => action | ||||
|         case Some(x) if(x.administrator) => action | ||||
|         case _ => Unauthorized() | ||||
|       } | ||||
|     } | ||||
| @@ -97,7 +97,7 @@ trait CollaboratorsAuthenticator { self: ControllerBase with RepositoryService = | ||||
|       defining(request.paths){ paths => | ||||
|         getRepository(paths(0), paths(1)).map { repository => | ||||
|           context.loginAccount match { | ||||
|             case Some(x) if(x.isAdmin) => action(repository) | ||||
|             case Some(x) if(x.administrator) => action(repository) | ||||
|             case Some(x) if(paths(0) == x.userName) => action(repository) | ||||
|             case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository) | ||||
|             case _ => Unauthorized() | ||||
| @@ -119,11 +119,11 @@ trait ReferrerAuthenticator { self: ControllerBase with RepositoryService => | ||||
|     { | ||||
|       defining(request.paths){ paths => | ||||
|         getRepository(paths(0), paths(1)).map { repository => | ||||
|           if(!repository.repository.isPrivate){ | ||||
|           if(!repository.repository.`private`){ | ||||
|             action(repository) | ||||
|           } else { | ||||
|             context.loginAccount match { | ||||
|               case Some(x) if(x.isAdmin) => action(repository) | ||||
|               case Some(x) if(x.administrator) => action(repository) | ||||
|               case Some(x) if(paths(0) == x.userName) => action(repository) | ||||
|               case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository) | ||||
|               case _ => Unauthorized() | ||||
| @@ -147,8 +147,8 @@ trait ReadableUsersAuthenticator { self: ControllerBase with RepositoryService = | ||||
|       defining(request.paths){ paths => | ||||
|         getRepository(paths(0), paths(1)).map { repository => | ||||
|           context.loginAccount match { | ||||
|             case Some(x) if(x.isAdmin) => action(repository) | ||||
|             case Some(x) if(!repository.repository.isPrivate) => action(repository) | ||||
|             case Some(x) if(x.administrator) => action(repository) | ||||
|             case Some(x) if(!repository.repository.`private`) => action(repository) | ||||
|             case Some(x) if(paths(0) == x.userName) => action(repository) | ||||
|             case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository) | ||||
|             case _ => Unauthorized() | ||||
| @@ -171,7 +171,7 @@ trait GroupManagerAuthenticator { self: ControllerBase with AccountService => | ||||
|       defining(request.paths){ paths => | ||||
|         context.loginAccount match { | ||||
|           case Some(x) if(getGroupMembers(paths(0)).exists { member => | ||||
|             member.userName == x.userName && member.isManager | ||||
|             member.userName == x.userName && member.manager | ||||
|           }) => action | ||||
|           case _ => Unauthorized() | ||||
|         } | ||||
|   | ||||
| @@ -30,7 +30,7 @@ trait Notifier extends RepositoryService with AccountService with IssuesService | ||||
|     ) | ||||
|     .distinct | ||||
|     .withFilter ( _ != context.loginAccount.get.userName )  // the operation in person is excluded | ||||
|     .foreach ( getAccountByUserName(_) filterNot (_.isGroupAccount) filterNot (LDAPUtil.isDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) ) | ||||
|     .foreach ( getAccountByUserName(_) filterNot (_.groupAccount) filterNot (LDAPUtil.isDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) ) | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -32,7 +32,7 @@ | ||||
|             </ul> | ||||
|             @helper.html.account("memberName", 200) | ||||
|             <input type="button" class="btn btn-default" value="Add" id="addMember"/> | ||||
|             <input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/> | ||||
|             <input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.manager).mkString(",")"/> | ||||
|             <div> | ||||
|               <span class="error" id="error-members"></span> | ||||
|             </div> | ||||
| @@ -103,7 +103,7 @@ $(function(){ | ||||
|   }); | ||||
|  | ||||
|   @members.map { member => | ||||
|     addMemberHTML('@member.userName', @member.isManager); | ||||
|     addMemberHTML('@member.userName', @member.manager); | ||||
|   } | ||||
|  | ||||
|   function addMemberHTML(userName, isManager){ | ||||
|   | ||||
| @@ -31,7 +31,7 @@ | ||||
|         <div class="col-md-8"> | ||||
|           <ul class="nav nav-tabs" style="margin-bottom: 5px;"> | ||||
|             <li@if(active == "repositories"){ class="active"}><a href="@url(account.userName)?tab=repositories">Repositories</a></li> | ||||
|             @if(account.isGroupAccount){ | ||||
|             @if(account.groupAccount){ | ||||
|               <li@if(active == "members"){ class="active"}><a href="@url(account.userName)?tab=members">Members</a></li> | ||||
|             } else { | ||||
|               <li@if(active == "activity"){ class="active"}><a href="@url(account.userName)?tab=activity">Public Activity</a></li> | ||||
| @@ -43,9 +43,9 @@ | ||||
|                 </div> | ||||
|               </li> | ||||
|             } | ||||
|             @if(loginAccount.isDefined && account.isGroupAccount && isGroupManager){ | ||||
|             @if(loginAccount.isDefined && account.groupAccount && isGroupManager){ | ||||
|               <li class="pull-right"> | ||||
|                 <div class="button-group"> | ||||
|                 <div class="button-groRepiosup"> | ||||
|                   <a href="@url(account.userName)/_editgroup" class="btn btn-default">Edit Group</a> | ||||
|                 </div> | ||||
|               </li> | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
|         <div class="repository-content"> | ||||
|           <div class="block-header"> | ||||
|             <a href="@url(repository)">@repository.name</a> | ||||
|             @if(repository.repository.isPrivate){ | ||||
|             @if(repository.repository.`private`){ | ||||
|               <i class="octicon octicon-lock"></i> | ||||
|             } | ||||
|           </div> | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
|             <input type="text" name="userName" id="userName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/> | ||||
|             @if(account.isDefined){ | ||||
|               <label for="removed"> | ||||
|                 <input type="checkbox" name="removed" id="removed" value="true" @if(account.get.isRemoved){checked}/> | ||||
|                 <input type="checkbox" name="removed" id="removed" value="true" @if(account.get.removed){checked}/> | ||||
|                 Disable | ||||
|               </label> | ||||
|               <div> | ||||
| @@ -53,10 +53,10 @@ | ||||
|           <fieldset class="form-group"> | ||||
|             <label class="strong">User Type:</label> | ||||
|             <label class="radio" for="userType_Normal"> | ||||
|               <input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.isAdmin){ checked}/> Normal | ||||
|               <input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.administrator){ checked}/> Normal | ||||
|             </label> | ||||
|             <label class="radio" for="userType_Admin"> | ||||
|               <input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.isAdmin){ checked}/> Administrator | ||||
|               <input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.administrator){ checked}/> Administrator | ||||
|             </label> | ||||
|           </fieldset> | ||||
|           <fieldset class="form-group"> | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|             <input type="text" name="groupName" id="groupName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/> | ||||
|             @if(account.isDefined){ | ||||
|               <label for="removed"> | ||||
|                 <input type="checkbox" name="removed" id="removed" value="true" @if(account.get.isRemoved){checked}/> | ||||
|                 <input type="checkbox" name="removed" id="removed" value="true" @if(account.get.removed){checked}/> | ||||
|                 Disable | ||||
|               </label> | ||||
|             } | ||||
| @@ -38,7 +38,7 @@ | ||||
|             </ul> | ||||
|             @helper.html.account("memberName", 200) | ||||
|             <input type="button" class="btn btn-default" value="Add" id="addMember"/> | ||||
|             <input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/> | ||||
|             <input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.manager).mkString(",")"/> | ||||
|             <div> | ||||
|               <span class="error" id="error-members"></span> | ||||
|             </div> | ||||
| @@ -98,7 +98,7 @@ $(function(){ | ||||
|   }); | ||||
|  | ||||
|   @members.map { member => | ||||
|     addMemberHTML('@member.userName', @member.isManager); | ||||
|     addMemberHTML('@member.userName', @member.manager); | ||||
|   } | ||||
|  | ||||
|   function addMemberHTML(userName, isManager){ | ||||
|   | ||||
| @@ -14,9 +14,9 @@ | ||||
|     <table class="table table-bordered table-hover"> | ||||
|       @users.map { account => | ||||
|         <tr> | ||||
|           <td @if(account.isRemoved){style="background-color: #dddddd;"}> | ||||
|           <td @if(account.removed){style="background-color: #dddddd;"}> | ||||
|             <div class="pull-right"> | ||||
|               @if(account.isGroupAccount){ | ||||
|               @if(account.groupAccount){ | ||||
|                 <a href="@path/admin/users/@account.userName/_editgroup">Edit</a> | ||||
|               } else { | ||||
|                 <a href="@path/admin/users/@account.userName/_edituser">Edit</a> | ||||
| @@ -25,16 +25,16 @@ | ||||
|             <div class="strong"> | ||||
|               @avatar(account.userName, 20) | ||||
|               <a href="@url(account.userName)">@account.userName</a> | ||||
|               @if(account.isGroupAccount){ | ||||
|               @if(account.groupAccount){ | ||||
|                 (Group) | ||||
|               } else { | ||||
|                 @if(account.isAdmin){ | ||||
|                 @if(account.administrator){ | ||||
|                   (Administrator) | ||||
|                 } else { | ||||
|                   (Normal) | ||||
|                 } | ||||
|               } | ||||
|               @if(account.isGroupAccount){ | ||||
|               @if(account.groupAccount){ | ||||
|                 @members(account.userName).map { userName => | ||||
|                   @avatar(userName, 20, tooltip = true) | ||||
|                 } | ||||
| @@ -42,7 +42,7 @@ | ||||
|             </div> | ||||
|             <div> | ||||
|               <hr> | ||||
|               @if(!account.isGroupAccount){ | ||||
|               @if(!account.groupAccount){ | ||||
|                 <i class="octicon octicon-mail"></i> @account.mailAddress | ||||
|               } | ||||
|               @account.url.map { url => | ||||
| @@ -52,7 +52,7 @@ | ||||
|             <div> | ||||
|               <span class="muted">Registered:</span> @datetime(account.registeredDate) | ||||
|               <span class="muted">Updated:</span> @datetime(account.updatedDate) | ||||
|               @if(!account.isGroupAccount){ | ||||
|               @if(!account.groupAccount){ | ||||
|                 <span class="muted">Last Login:</span> @account.lastLoginDate.map(datetime) | ||||
|               } | ||||
|             </div> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| @import gitbucket.core.service.RepositoryService | ||||
| @import context._ | ||||
| @import gitbucket.core.view.helpers._ | ||||
| @if(repository.repository.isPrivate){ | ||||
| @if(repository.repository.`private`){ | ||||
|   <i class="@{if(large){"mega-"}}octicon octicon-lock"></i> | ||||
| } else { | ||||
|   @if(repository.repository.originUserName.isDefined){ | ||||
|   | ||||
| @@ -36,7 +36,7 @@ | ||||
|     <script src="@assets/vendors/facebox/facebox.js"></script> | ||||
|     <script src="@assets/vendors/jquery-hotkeys/jquery.hotkeys.js"></script> | ||||
|     @repository.map { repository => | ||||
|       @if(!repository.repository.isPrivate){ | ||||
|       @if(!repository.repository.`private`){ | ||||
|         <meta name="go-import" content="@context.baseUrl.replaceFirst("^https?://", "")/@repository.owner/@repository.name git @repository.httpUrl" /> | ||||
|       } | ||||
|     } | ||||
| @@ -92,7 +92,7 @@ | ||||
|                 <ul class="dropdown-menu pull-right"> | ||||
|                   <li><a href="@url(loginAccount.get.userName)">Your profile</a></li> | ||||
|                   <li><a href="@url(loginAccount.get.userName)/_edit">Account settings</a></li> | ||||
|                   @if(loginAccount.get.isAdmin){ | ||||
|                   @if(loginAccount.get.administrator){ | ||||
|                     <li><a href="@path/admin/users">System administration</a></li> | ||||
|                   } | ||||
|                   <li><a href="@path/signout">Sign out</a></li> | ||||
|   | ||||
| @@ -63,7 +63,7 @@ | ||||
|       @menuitem("/issues", "issues" , "issue-opened" , "Issues", repository.issueCount) | ||||
|       @menuitem("/pulls" , "pulls"  , "git-pull-request" , "Pull Requests", repository.pullCount) | ||||
|       @menuitem("/wiki"  , "wiki"   , "book"  , "Wiki") | ||||
|       @if(loginAccount.isDefined && (loginAccount.get.isAdmin || repository.managers.contains(loginAccount.get.userName))){ | ||||
|       @if(loginAccount.isDefined && (loginAccount.get.administrator || repository.managers.contains(loginAccount.get.userName))){ | ||||
|         @menuitem("/settings" , "settings" , "tools", "Settings") | ||||
|       } | ||||
|     </ul> | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
|             <fieldset class="margin"> | ||||
|               <label class="radio"> | ||||
|                 <input type="radio" name="isPrivate" value="false" | ||||
|                   @if(!repository.repository.isPrivate              ){ checked  } | ||||
|                   @if(!repository.repository.`private`              ){ checked  } | ||||
|                   @if(repository.repository.parentUserName.isDefined){ disabled } | ||||
|                 > | ||||
|                 <span class="strong"><i class="octicon octicon-repo"></i> Public</span><br> | ||||
| @@ -31,7 +31,7 @@ | ||||
|               </label> | ||||
|               <label class="radio"> | ||||
|                 <input type="radio" name="isPrivate" value="true" | ||||
|                   @if(repository.repository.isPrivate               ){ checked  } | ||||
|                   @if(repository.repository.`private`               ){ checked  } | ||||
|                   @if(repository.repository.parentUserName.isDefined){ disabled } | ||||
|                 > | ||||
|                 <span class="strong"><i class="octicon octicon-lock"></i> Private</span><br> | ||||
|   | ||||
| @@ -84,14 +84,14 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar { | ||||
|       fullName       = "user@localhost", | ||||
|       mailAddress    = "", | ||||
|       password       = "", | ||||
|       isAdmin        = false, | ||||
|       administrator  = false, | ||||
|       url            = None, | ||||
|       registeredDate = new Date(), | ||||
|       updatedDate    = new Date(), | ||||
|       lastLoginDate  = None, | ||||
|       image          = image, | ||||
|       isGroupAccount = false, | ||||
|       isRemoved      = false) | ||||
|       groupAccount   = false, | ||||
|       removed        = false) | ||||
|  | ||||
|   private def createSystemSettings(useGravatar: Boolean) = | ||||
|     SystemSettings( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user