mirror of
				https://github.com/gitbucket/gitbucket.git
				synced 2025-10-31 02:25:59 +01:00 
			
		
		
		
	Implementing authentication.
This commit is contained in:
		| @@ -1,9 +1,9 @@ | ||||
| package app | ||||
|  | ||||
| import model.Account | ||||
| import org.scalatra._ | ||||
| import org.scalatra.json._ | ||||
| import org.json4s._ | ||||
| import org.json4s.jackson._ | ||||
| import jp.sf.amateras.scalatra.forms._ | ||||
|  | ||||
| /** | ||||
| @@ -13,11 +13,35 @@ abstract class ControllerBase extends ScalatraFilter with ClientSideValidationFo | ||||
|    | ||||
|   implicit val jsonFormats = DefaultFormats | ||||
|    | ||||
|   implicit def context: Context = Context(servletContext.getContextPath, LoginUser) | ||||
|   implicit def context: Context = Context(servletContext.getContextPath, LoginAccount) | ||||
|    | ||||
|   // TODO get from session | ||||
|   private val LoginUser = "admin" //System.getProperty("user.name") | ||||
|   private def LoginAccount: Option[Account] = { | ||||
|     session.get("LOGIN_ACCOUNT") match { | ||||
|       case Some(x: Account) => Some(x) | ||||
|       case _ => None | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   protected def usersOnly(action: => Any) = { | ||||
|     { | ||||
|       context.loginAccount match { | ||||
|         case Some(x) => action | ||||
|         case None    => redirect("/signin") | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   protected def usersOnly[T](action: T => Any) = { | ||||
|     (form: T) => { | ||||
|       context.loginAccount match { | ||||
|         case Some(x) => action(form) | ||||
|         case None    => redirect("/signin") | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| //  protected def adminOnly() | ||||
|  | ||||
| } | ||||
|  | ||||
| case class Context(path: String, loginUser: String) | ||||
| case class Context(path: String, loginAccount: Option[Account]) | ||||
| @@ -8,12 +8,13 @@ import org.eclipse.jgit.lib._ | ||||
| import org.apache.commons.io._ | ||||
| import jp.sf.amateras.scalatra.forms._ | ||||
|  | ||||
| class CreateRepositoryController extends CreateRepositoryControllerBase with ProjectService with AccountService | ||||
| class CreateRepositoryController extends CreateRepositoryControllerBase | ||||
|   with ProjectService with AccountService with WikiService | ||||
|  | ||||
| /** | ||||
|  * Creates new repository. | ||||
|  */ | ||||
| trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectService => | ||||
| trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectService with WikiService => | ||||
|  | ||||
|   case class RepositoryCreationForm(name: String, description: String) // TODO Option | ||||
|  | ||||
| @@ -25,19 +26,21 @@ trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectServi | ||||
|   /** | ||||
|    * Show the new repository form. | ||||
|    */ | ||||
|   get("/new") { | ||||
|   get("/new")(usersOnly { | ||||
|     html.newrepo() | ||||
|   } | ||||
|   }) | ||||
|    | ||||
|   /** | ||||
|    * Create new repository. | ||||
|    */ | ||||
|   post("/new", form) { form => | ||||
|   post("/new", form)(usersOnly { form => | ||||
|     val loginUserName = context.loginAccount.get.userName | ||||
|  | ||||
|     // Insert to the database at first | ||||
|     createProject(form.name, context.loginUser, Some(form.description)) | ||||
|     createProject(form.name, loginUserName, Some(form.description)) | ||||
|  | ||||
|     // Create the actual repository | ||||
|     val gitdir = getRepositoryDir(context.loginUser, form.name) | ||||
|     val gitdir = getRepositoryDir(loginUserName, form.name) | ||||
|     val repository = new RepositoryBuilder().setGitDir(gitdir).setBare.build | ||||
|  | ||||
|     repository.create | ||||
| @@ -46,7 +49,7 @@ trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectServi | ||||
|     config.setBoolean("http", null, "receivepack", true) | ||||
|     config.save | ||||
|  | ||||
|     val tmpdir = getInitRepositoryDir(context.loginUser, form.name) | ||||
|     val tmpdir = getInitRepositoryDir(loginUserName, form.name) | ||||
|     try { | ||||
|       // Clone the repository | ||||
|       Git.cloneRepository.setURI(gitdir.toURI.toString).setDirectory(tmpdir).call | ||||
| @@ -67,9 +70,12 @@ trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectServi | ||||
|       FileUtils.deleteDirectory(tmpdir) | ||||
|     } | ||||
|  | ||||
|     // Create Wiki repository | ||||
|     createWikiRepository(context.loginAccount.get, form.name) | ||||
|  | ||||
|     // redirect to the repository | ||||
|     redirect("/%s/%s".format(context.loginUser, form.name)) | ||||
|   } | ||||
|     redirect("/%s/%s".format(loginUserName, form.name)) | ||||
|   }) | ||||
|    | ||||
|   /** | ||||
|    * Constraint for the repository name. | ||||
| @@ -78,7 +84,7 @@ trait CreateRepositoryControllerBase extends ControllerBase { self: ProjectServi | ||||
|     def validate(name: String, value: String): Option[String] = { | ||||
|       if(!value.matches("^[a-zA-Z0-9\\-_]+$")){ | ||||
|         Some("Repository name contains invalid character.") | ||||
|       } else if(getRepositories(context.loginUser, servletContext).contains(value)){ | ||||
|       } else if(getRepositories(context.loginAccount.get.userName, servletContext).contains(value)){ | ||||
|         Some("Repository already exists.") | ||||
|       } else { | ||||
|         None | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| package app | ||||
|  | ||||
| import service._ | ||||
| import jp.sf.amateras.scalatra.forms._ | ||||
|  | ||||
| class SignInController extends ControllerBase { | ||||
| class SignInController extends SignInControllerBase with AccountService | ||||
|  | ||||
| trait SignInControllerBase extends ControllerBase { self: AccountService => | ||||
|    | ||||
|   case class SignInForm(email: String, password: String) | ||||
|    | ||||
| @@ -16,7 +19,18 @@ class SignInController extends ControllerBase { | ||||
|   } | ||||
|  | ||||
|   post("/signin", form){ form => | ||||
|     // TODO check email and password | ||||
|     redirect("/%s".format(context.loginUser)) | ||||
|     val account = getAccountByUserName(form.email) | ||||
|     if(account.isEmpty || account.get.password != form.password){ | ||||
|       redirect("/signin") | ||||
|     } else { | ||||
|       session.setAttribute("LOGIN_ACCOUNT", account.get) | ||||
|       redirect("/%s".format(account.get.userName)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   get("/signout"){ | ||||
|     session.invalidate | ||||
|     redirect("/signin") | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -94,7 +94,7 @@ trait WikiControllerBase extends ControllerBase { self: WikiService with Project | ||||
|     val repository = params("repository") | ||||
|      | ||||
|     saveWikiPage(owner, repository, form.currentPageName, form.pageName,  | ||||
|         form.content, context.loginUser, form.message.getOrElse("")) | ||||
|         form.content, context.loginAccount.get, form.message.getOrElse("")) | ||||
|      | ||||
|     redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName)) | ||||
|   } | ||||
| @@ -111,7 +111,7 @@ trait WikiControllerBase extends ControllerBase { self: WikiService with Project | ||||
|     val repository = params("repository") | ||||
|      | ||||
|     saveWikiPage(owner, repository, form.currentPageName, form.pageName,  | ||||
|         form.content, context.loginUser, form.message.getOrElse("")) | ||||
|         form.content, context.loginAccount.get, form.message.getOrElse("")) | ||||
|      | ||||
|     redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName)) | ||||
|   } | ||||
| @@ -121,7 +121,7 @@ trait WikiControllerBase extends ControllerBase { self: WikiService with Project | ||||
|     val repository = params("repository") | ||||
|     val page       = params("page") | ||||
|      | ||||
|     deleteWikiPage(owner, repository, page, context.loginUser, "Delete %s".format(page)) | ||||
|     deleteWikiPage(owner, repository, page, context.loginAccount.get.userName, "Delete %s".format(page)) | ||||
|      | ||||
|     redirect("%s/%s/wiki".format(owner, repository)) | ||||
|   } | ||||
|   | ||||
| @@ -34,17 +34,16 @@ object WikiService { | ||||
| } | ||||
|  | ||||
| trait WikiService { | ||||
|    | ||||
|   import WikiService._ | ||||
|    | ||||
|   // TODO synchronized? | ||||
|   def createWikiRepository(owner: String, repository: String): Unit = { | ||||
|     val dir = Directory.getWikiRepositoryDir(owner, repository) | ||||
|   def createWikiRepository(owner: model.Account, repository: String): Unit = { | ||||
|     val dir = Directory.getWikiRepositoryDir(owner.userName, repository) | ||||
|     if(!dir.exists){ | ||||
|       val repo = new RepositoryBuilder().setGitDir(dir).setBare.build | ||||
|       try { | ||||
|         repo.create | ||||
|         saveWikiPage(owner, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit") | ||||
|         saveWikiPage(owner.userName, repository, "Home", "Home", "Welcome to the %s wiki!!".format(repository), owner, "Initial Commit") | ||||
|       } finally { | ||||
|         repo.close | ||||
|       } | ||||
| @@ -55,9 +54,6 @@ trait WikiService { | ||||
|    * Returns the wiki page. | ||||
|    */ | ||||
|   def getWikiPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = { | ||||
|     // TODO create wiki repository in the repository setting changing. | ||||
|     createWikiRepository(owner, repository) | ||||
|      | ||||
|     JGitUtil.withGit(Directory.getWikiRepositoryDir(owner, repository)){ git => | ||||
|       try { | ||||
|         JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file => | ||||
| @@ -82,10 +78,7 @@ trait WikiService { | ||||
|    * Save the wiki page. | ||||
|    */ | ||||
|   def saveWikiPage(owner: String, repository: String, currentPageName: String, newPageName: String, | ||||
|       content: String, committer: String, message: String): Unit = { | ||||
|      | ||||
|     // TODO create wiki repository in the repository setting changing. | ||||
|     createWikiRepository(owner, repository) | ||||
|       content: String, committer: model.Account, message: String): Unit = { | ||||
|  | ||||
|     val workDir = Directory.getWikiWorkDir(owner, repository) | ||||
|      | ||||
| @@ -118,8 +111,7 @@ trait WikiService { | ||||
|      | ||||
|       // commit and push | ||||
|       if(added || deleted){ | ||||
|         // TODO committer's mail address | ||||
|         git.commit.setAuthor(committer, committer + "@devnull").setMessage(message).call | ||||
|         git.commit.setCommitter(committer.userName, committer.mailAddress).setMessage(message).call | ||||
|         git.push.call | ||||
|       } | ||||
|     } | ||||
| @@ -129,8 +121,6 @@ trait WikiService { | ||||
|    * Delete the wiki page. | ||||
|    */ | ||||
|   def deleteWikiPage(owner: String, repository: String, pageName: String, committer: String, message: String): Unit = { | ||||
|     // TODO create wiki repository in the repository setting changing. | ||||
|     createWikiRepository(owner, repository) | ||||
|      | ||||
|     val workDir = Directory.getWikiWorkDir(owner, repository) | ||||
|      | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| @main("GitBucket"){ | ||||
|   <h1>GitBucket</h1> | ||||
|   <ul> | ||||
|     <li><a href="@path/@context.loginUser">User page</a></li> | ||||
|     <li><a href="@path/@context.loginAccount.get.userName">User page</a></li> | ||||
|     <li><a href="@path/new">Create new repository</a></li> | ||||
|   </ul> | ||||
| } | ||||
| @@ -31,10 +31,14 @@ | ||||
|           <a class="brand" href="#">GitBucket</a> | ||||
|           <div class="nav-collapse collapse"> | ||||
|             <ul class="nav pull-right"> | ||||
|               @if(loginAccount.isDefined){ | ||||
|                 <li><a href="@path/new">New repo</a></li> | ||||
|               <li><a href="@path/@context.loginUser">Account</a></li> | ||||
|                 <li><a href="@path/@loginAccount.get.userName">Account</a></li> | ||||
|                 <li><a href="#users">Users</a></li> | ||||
|               <li><a href="#contact">Sign out</a></li> | ||||
|                 <li><a href="@path/signout">Sign out</a></li> | ||||
|               } else { | ||||
|                 <li><a href="@path/signin">Sign in</a></li> | ||||
|               } | ||||
|             </ul> | ||||
|           </div><!--/.nav-collapse --> | ||||
|         </div> | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
|         </ul> | ||||
|         @repositories.map { repository => | ||||
|         <div class="block"> | ||||
|           <div class="block-header-2"><a href="@path/@user/@repository.name">@repository.name</a></div> | ||||
|           <div class="block-header-2"><a href="@path/@repository.owner/@repository.name">@repository.name</a></div> | ||||
|           <div>@repository.project.description</div> | ||||
|           <div><span class="description small">Last updated: @repository.project.lastActivityDate</span></div> | ||||
|         </div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user