mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-06 13:35:50 +01:00
(refs #115)Adding SSH Key form is available
This commit is contained in:
@@ -3,6 +3,7 @@ ALTER TABLE GROUP_MEMBER ADD COLUMN MANAGER BOOLEAN DEFAULT FALSE;
|
|||||||
CREATE TABLE SSH_KEY (
|
CREATE TABLE SSH_KEY (
|
||||||
USER_NAME VARCHAR(100) NOT NULL,
|
USER_NAME VARCHAR(100) NOT NULL,
|
||||||
SSH_KEY_ID INT AUTO_INCREMENT,
|
SSH_KEY_ID INT AUTO_INCREMENT,
|
||||||
|
TITLE VARCHAR(100) NOT NULL,
|
||||||
PUBLIC_KEY TEXT NOT NULL
|
PUBLIC_KEY TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import org.eclipse.jgit.dircache.DirCache
|
|||||||
import model.GroupMember
|
import model.GroupMember
|
||||||
|
|
||||||
class AccountController extends AccountControllerBase
|
class AccountController extends AccountControllerBase
|
||||||
with AccountService with RepositoryService with ActivityService with WikiService with LabelsService
|
with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
||||||
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
|
||||||
|
|
||||||
trait AccountControllerBase extends AccountManagementControllerBase {
|
trait AccountControllerBase extends AccountManagementControllerBase {
|
||||||
self: AccountService with RepositoryService with ActivityService with WikiService with LabelsService
|
self: AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
|
||||||
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator =>
|
with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator =>
|
||||||
|
|
||||||
case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String,
|
case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String,
|
||||||
@@ -27,6 +27,8 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
case class AccountEditForm(password: Option[String], fullName: String, mailAddress: String,
|
case class AccountEditForm(password: Option[String], fullName: String, mailAddress: String,
|
||||||
url: Option[String], fileId: Option[String], clearImage: Boolean)
|
url: Option[String], fileId: Option[String], clearImage: Boolean)
|
||||||
|
|
||||||
|
case class SshKeyForm(title: String, publicKey: String)
|
||||||
|
|
||||||
val newForm = mapping(
|
val newForm = mapping(
|
||||||
"userName" -> trim(label("User name" , text(required, maxlength(100), identifier, uniqueUserName))),
|
"userName" -> trim(label("User name" , text(required, maxlength(100), identifier, uniqueUserName))),
|
||||||
"password" -> trim(label("Password" , text(required, maxlength(20)))),
|
"password" -> trim(label("Password" , text(required, maxlength(20)))),
|
||||||
@@ -45,6 +47,11 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
"clearImage" -> trim(label("Clear image" , boolean()))
|
"clearImage" -> trim(label("Clear image" , boolean()))
|
||||||
)(AccountEditForm.apply)
|
)(AccountEditForm.apply)
|
||||||
|
|
||||||
|
val sshKeyForm = mapping(
|
||||||
|
"title" -> trim(label("Title", text(required, maxlength(100)))),
|
||||||
|
"publicKey" -> trim(label("Key" , text(required)))
|
||||||
|
)(SshKeyForm.apply)
|
||||||
|
|
||||||
case class NewGroupForm(groupName: String, url: Option[String], fileId: Option[String], members: String)
|
case class NewGroupForm(groupName: String, url: Option[String], fileId: Option[String], members: String)
|
||||||
case class EditGroupForm(groupName: String, url: Option[String], fileId: Option[String], members: String, clearImage: Boolean)
|
case class EditGroupForm(groupName: String, url: Option[String], fileId: Option[String], members: String, clearImage: Boolean)
|
||||||
|
|
||||||
@@ -164,6 +171,19 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
redirect("/")
|
redirect("/")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
get("/:userName/_ssh")(oneselfOnly {
|
||||||
|
val userName = params("userName")
|
||||||
|
getAccountByUserName(userName).map { x =>
|
||||||
|
account.html.ssh(x, getPublicKeys(x.userName), flash.get("info"))
|
||||||
|
} getOrElse NotFound
|
||||||
|
})
|
||||||
|
|
||||||
|
post("/:userName/_ssh", sshKeyForm)(oneselfOnly { form =>
|
||||||
|
val userName = params("userName")
|
||||||
|
addPublicKey(userName, form.title, form.publicKey)
|
||||||
|
redirect(s"/${userName}/_ssh")
|
||||||
|
})
|
||||||
|
|
||||||
get("/register"){
|
get("/register"){
|
||||||
if(loadSystemSettings().allowAccountRegistration){
|
if(loadSystemSettings().allowAccountRegistration){
|
||||||
if(context.loginAccount.isDefined){
|
if(context.loginAccount.isDefined){
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import scala.slick.driver.H2Driver.simple._
|
|||||||
|
|
||||||
object SshKeys extends Table[SshKey]("SSH_KEY") {
|
object SshKeys extends Table[SshKey]("SSH_KEY") {
|
||||||
def userName = column[String]("USER_NAME")
|
def userName = column[String]("USER_NAME")
|
||||||
def sshKeyId = column[Int]("SSH_KEY")
|
def sshKeyId = column[Int]("SSH_KEY_ID", O AutoInc)
|
||||||
|
def title = column[String]("TITLE")
|
||||||
def publicKey = column[String]("PUBLIC_KEY")
|
def publicKey = column[String]("PUBLIC_KEY")
|
||||||
def * = userName ~ sshKeyId ~ publicKey <> (SshKey, SshKey.unapply _)
|
|
||||||
|
def ins = userName ~ title ~ publicKey returning sshKeyId
|
||||||
|
def * = userName ~ sshKeyId ~ title ~ publicKey <> (SshKey, SshKey.unapply _)
|
||||||
|
|
||||||
def byPrimaryKey(userName: String, sshKeyId: Int) = (this.userName is userName.bind) && (this.sshKeyId is sshKeyId.bind)
|
def byPrimaryKey(userName: String, sshKeyId: Int) = (this.userName is userName.bind) && (this.sshKeyId is sshKeyId.bind)
|
||||||
}
|
}
|
||||||
@@ -14,5 +17,6 @@ object SshKeys extends Table[SshKey]("SSH_KEY") {
|
|||||||
case class SshKey(
|
case class SshKey(
|
||||||
userName: String,
|
userName: String,
|
||||||
sshKeyId: Int,
|
sshKeyId: Int,
|
||||||
|
title: String,
|
||||||
publicKey: String
|
publicKey: String
|
||||||
)
|
)
|
||||||
|
|||||||
15
src/main/scala/service/SshKeyService.scala
Normal file
15
src/main/scala/service/SshKeyService.scala
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import model._
|
||||||
|
import scala.slick.driver.H2Driver.simple._
|
||||||
|
import Database.threadLocalSession
|
||||||
|
|
||||||
|
trait SshKeyService {
|
||||||
|
|
||||||
|
def addPublicKey(userName: String, title: String, publicKey: String): Unit =
|
||||||
|
SshKeys.ins insert (userName, title, publicKey)
|
||||||
|
|
||||||
|
def getPublicKeys(userName: String): List[SshKey] =
|
||||||
|
Query(SshKeys).filter(_.userName is userName.bind).sortBy(_.sshKeyId).list
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,7 +12,8 @@ import org.eclipse.jgit.lib.Constants
|
|||||||
object DummyData {
|
object DummyData {
|
||||||
val userPublicKeys = List(
|
val userPublicKeys = List(
|
||||||
"ssh-rsa AAB3NzaC1yc2EAAAADAQABAAABAQDRzuX0WtSLzCY45nEhfFDPXzYGmvQdqnOgOUY4yGL5io/2ztyUvJdhWowkyakeoPxVk/jIP7Tu8Are5TuSD+fJp7aUbZW2CYOEsxo8cwndh/ezIX6RFjlu+xvKvZ8G7BtFLlLCcnza9uB+uEAyPH5HvGQLdV7dXctLfFqXPTr1p1RjSI7Noubm+vN4n9108rILd32MlhQiToXjL4HKWWwmppaln6bEsonOQW4/GieRjQeyWDkbVekIofnedjWl4+W0kAA+WosNwRFShgsaJLfU964HT/cGjK5auqOG+nATY0suECnxAK+5Wb6jXXYNmKiIMHypeXG1Qy2wMyMB1Gq9 tanacasino-local",
|
"ssh-rsa AAB3NzaC1yc2EAAAADAQABAAABAQDRzuX0WtSLzCY45nEhfFDPXzYGmvQdqnOgOUY4yGL5io/2ztyUvJdhWowkyakeoPxVk/jIP7Tu8Are5TuSD+fJp7aUbZW2CYOEsxo8cwndh/ezIX6RFjlu+xvKvZ8G7BtFLlLCcnza9uB+uEAyPH5HvGQLdV7dXctLfFqXPTr1p1RjSI7Noubm+vN4n9108rILd32MlhQiToXjL4HKWWwmppaln6bEsonOQW4/GieRjQeyWDkbVekIofnedjWl4+W0kAA+WosNwRFShgsaJLfU964HT/cGjK5auqOG+nATY0suECnxAK+5Wb6jXXYNmKiIMHypeXG1Qy2wMyMB1Gq9 tanacasino-local",
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRzuX0WtSLzCY45nEhfFDPXzYGmvQdqnOgOUY4yGL5io/2ztyUvJdhWowkyakeoPxVk/jIP7Tu8Are5TuSD+fJp7aUbZW2CYOEsxo8cwndh/ezIX6RFjlu+xvKvZ8G7BtFLlLCcnza9uB+uEAyPH5HvGQLdV7dXctLfFqXPTr1p1RjSI7Noubm+vN4n9108rILd32MlhQiToXjL4HKWWwmppaln6bEsonOQW4/GieRjQeyWDkbVekIofnedjWl4+W0kAA+WosNwRFShgsaJLfU964HT/cGjK5auqOG+nATY0suECnxAK+5Wb6jXXYNmKiIMHypeXG1Qy2wMyMB1Gq9 tanacasino-local"
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRzuX0WtSLzCY45nEhfFDPXzYGmvQdqnOgOUY4yGL5io/2ztyUvJdhWowkyakeoPxVk/jIP7Tu8Are5TuSD+fJp7aUbZW2CYOEsxo8cwndh/ezIX6RFjlu+xvKvZ8G7BtFLlLCcnza9uB+uEAyPH5HvGQLdV7dXctLfFqXPTr1p1RjSI7Noubm+vN4n9108rILd32MlhQiToXjL4HKWWwmppaln6bEsonOQW4/GieRjQeyWDkbVekIofnedjWl4+W0kAA+WosNwRFShgsaJLfU964HT/cGjK5auqOG+nATY0suECnxAK+5Wb6jXXYNmKiIMHypeXG1Qy2wMyMB1Gq9 tanacasino-local",
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAxBEtdwpE5PaClaEq2WY369einovW2ZUOXFKndY4z8RN7S3H4G1whMJVIsj2lrw1k+ranzNmOEHFoRKO0/XIE/2mSaGOawKG76vKEA/q7A0Zw8hMcdIBPaqMhrb/K7KyJiJtcvARelO76mUGv9ucA6DqvsuPjGalqhdp9eSq+1VE= naoki@your-4v4sjfo73c"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,18 @@
|
|||||||
@import context._
|
@import context._
|
||||||
@import view.helpers._
|
@import view.helpers._
|
||||||
@html.main((if(account.isDefined) "Edit your profile" else "Create your account")){
|
@html.main((if(account.isDefined) "Edit your profile" else "Create your account")){
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span3">
|
||||||
|
@menu("profile")
|
||||||
|
</div>
|
||||||
|
<div class="span9">
|
||||||
|
<form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{@path/register}" method="POST" validate="true">
|
||||||
@if(account.isDefined){
|
@if(account.isDefined){
|
||||||
<h3>Edit your profile</h3>
|
<h3>Edit your profile</h3>
|
||||||
} else {
|
} else {
|
||||||
<h3>Create your account</h3>
|
<h3>Create your account</h3>
|
||||||
}
|
}
|
||||||
@helper.html.information(info)
|
@helper.html.information(info)
|
||||||
<form action="@if(account.isDefined){@url(account.get.userName)/_edit}else{@path/register}" method="POST" validate="true">
|
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span6">
|
<div class="span6">
|
||||||
@if(account.isEmpty){
|
@if(account.isEmpty){
|
||||||
@@ -43,7 +48,7 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="url" class="strong">URL (optional):</label>
|
<label for="url" class="strong">URL (optional):</label>
|
||||||
<input type="text" name="url" id="url" style="width: 400px;" value="@account.map(_.url)"/>
|
<input type="text" name="url" id="url" style="width: 300px;" value="@account.map(_.url)"/>
|
||||||
<span id="error-url" class="error"></span>
|
<span id="error-url" class="error"></span>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,6 +71,8 @@
|
|||||||
}
|
}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
<script>
|
<script>
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|||||||
12
src/main/twirl/account/menu.scala.html
Normal file
12
src/main/twirl/account/menu.scala.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@(active: String)(implicit context: app.Context)
|
||||||
|
@import context._
|
||||||
|
<div class="box">
|
||||||
|
<ul class="nav nav-tabs nav-stacked side-menu">
|
||||||
|
<li@if(active=="profile"){ class="active"}>
|
||||||
|
<a href="@path/@loginAccount.get.userName/_edit">Profile</a>
|
||||||
|
</li>
|
||||||
|
<li@if(active=="ssh"){ class="active"}>
|
||||||
|
<a href="@path/@loginAccount.get.userName/_ssh">SSH Keys</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
39
src/main/twirl/account/ssh.scala.html
Normal file
39
src/main/twirl/account/ssh.scala.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
@(account: model.Account, sshKeys: List[model.SshKey], info: Option[Any])(implicit context: app.Context)
|
||||||
|
@import context._
|
||||||
|
@import view.helpers._
|
||||||
|
@html.main("SSH Keys"){
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span3">
|
||||||
|
@menu("ssh")
|
||||||
|
</div>
|
||||||
|
<div class="span9">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">SSH Keys</div>
|
||||||
|
<div class="box-content">
|
||||||
|
@sshKeys.map { sshKey =>
|
||||||
|
<strong>@sshKey.title</strong>
|
||||||
|
<a href="#" class="btn btn-mini btn-danger pull-right">Delete</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="POST" action="@path/@account.userName/_ssh" validate="true">
|
||||||
|
<div class="box">
|
||||||
|
<div class="box-header">Add an SSH Key</div>
|
||||||
|
<div class="box-content">
|
||||||
|
<fieldset>
|
||||||
|
<label for="title" class="strong">Title</label>
|
||||||
|
<div><span id="error-title" class="error"></span></div>
|
||||||
|
<input type="text" name="title" id="title" style="width: 400px;"/>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<label for="publicKey" class="strong">Key</label>
|
||||||
|
<div><span id="error-publicKey" class="error"></span></div>
|
||||||
|
<textarea name="publicKey" id="publicKey" style="width: 600px; height: 250px;"></textarea>
|
||||||
|
</fieldset>
|
||||||
|
<input type="submit" class="btn btn-success" value="Add"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user