mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-10 07:25:50 +01:00
(refs #115)Add repository permission checking
This commit is contained in:
@@ -9,7 +9,7 @@ import util.Directory._
|
|||||||
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
|
import org.eclipse.jgit.transport.{ReceivePack, UploadPack}
|
||||||
import org.apache.sshd.server.command.UnknownCommand
|
import org.apache.sshd.server.command.UnknownCommand
|
||||||
import servlet.{Database, CommitLogHook}
|
import servlet.{Database, CommitLogHook}
|
||||||
import service.SystemSettingsService
|
import service.{AccountService, RepositoryService, SystemSettingsService}
|
||||||
import org.eclipse.jgit.errors.RepositoryNotFoundException
|
import org.eclipse.jgit.errors.RepositoryNotFoundException
|
||||||
import javax.servlet.ServletContext
|
import javax.servlet.ServletContext
|
||||||
|
|
||||||
@@ -18,8 +18,10 @@ object GitCommand {
|
|||||||
val CommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-_.]+).git'\Z""".r
|
val CommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-_.]+).git'\Z""".r
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class GitCommand(val command: String) extends Command {
|
abstract class GitCommand(val context: ServletContext, val command: String) extends Command {
|
||||||
protected val logger = LoggerFactory.getLogger(classOf[GitCommand])
|
self: RepositoryService with AccountService =>
|
||||||
|
|
||||||
|
private val logger = LoggerFactory.getLogger(classOf[GitCommand])
|
||||||
protected val (gitCommand, owner, repositoryName) = parseCommand
|
protected val (gitCommand, owner, repositoryName) = parseCommand
|
||||||
protected var err: OutputStream = null
|
protected var err: OutputStream = null
|
||||||
protected var in: InputStream = null
|
protected var in: InputStream = null
|
||||||
@@ -30,6 +32,7 @@ abstract class GitCommand(val command: String) extends Command {
|
|||||||
|
|
||||||
private def newTask(user: String): Runnable = new Runnable {
|
private def newTask(user: String): Runnable = new Runnable {
|
||||||
override def run(): Unit = {
|
override def run(): Unit = {
|
||||||
|
Database(context) withTransaction {
|
||||||
try {
|
try {
|
||||||
runTask(user)
|
runTask(user)
|
||||||
callback.onExit(0)
|
callback.onExit(0)
|
||||||
@@ -43,6 +46,7 @@ abstract class GitCommand(val command: String) extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override def start(env: Environment): Unit = {
|
override def start(env: Environment): Unit = {
|
||||||
logger.info(s"start command : " + command)
|
logger.info(s"start command : " + command)
|
||||||
@@ -80,36 +84,49 @@ abstract class GitCommand(val command: String) extends Command {
|
|||||||
val repositoryName = split(1).substring(1, split(1).length - 5).split("/")(2)
|
val repositoryName = split(1).substring(1, split(1).length - 5).split("/")(2)
|
||||||
(gitCommand, owner, repositoryName)
|
(gitCommand, owner, repositoryName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected def isWritableUser(username: String, repositoryInfo: RepositoryService.RepositoryInfo): Boolean =
|
||||||
|
getAccountByUserName(username) match {
|
||||||
|
case Some(account) => hasWritePermission(repositoryInfo.owner, repositoryInfo.name, Some(account))
|
||||||
|
case None => false
|
||||||
}
|
}
|
||||||
|
|
||||||
class GitUploadPack(context: ServletContext, override val command: String) extends GitCommand(command: String) {
|
}
|
||||||
|
|
||||||
|
class GitUploadPack(context: ServletContext, command: String) extends GitCommand(context, command)
|
||||||
|
with RepositoryService with AccountService {
|
||||||
|
|
||||||
override protected def runTask(user: String): Unit = {
|
override protected def runTask(user: String): Unit = {
|
||||||
using(Git.open(getRepositoryDir(owner, repositoryName))) {
|
getRepository(owner, repositoryName, null).foreach { repositoryInfo =>
|
||||||
git =>
|
if(!repositoryInfo.repository.isPrivate || isWritableUser(user, repositoryInfo)){
|
||||||
|
using(Git.open(getRepositoryDir(owner, repositoryName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val upload = new UploadPack(repository)
|
val upload = new UploadPack(repository)
|
||||||
upload.upload(in, out, err)
|
upload.upload(in, out, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class GitReceivePack(context: ServletContext, override val command: String) extends GitCommand(command: String) with SystemSettingsService {
|
class GitReceivePack(context: ServletContext, command: String) extends GitCommand(context, command)
|
||||||
|
with SystemSettingsService with RepositoryService with AccountService {
|
||||||
// TODO Correct this info. where i get base url?
|
// TODO Correct this info. where i get base url?
|
||||||
val BaseURL: String = loadSystemSettings().baseUrl.getOrElse("http://localhost:8080")
|
val BaseURL: String = loadSystemSettings().baseUrl.getOrElse("http://localhost:8080")
|
||||||
|
|
||||||
override protected def runTask(user: String): Unit = {
|
override protected def runTask(user: String): Unit = {
|
||||||
using(Git.open(getRepositoryDir(owner, repositoryName))) {
|
getRepository(owner, repositoryName, null).foreach { repositoryInfo =>
|
||||||
git =>
|
if(isWritableUser(user, repositoryInfo)){
|
||||||
|
using(Git.open(getRepositoryDir(owner, repositoryName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val receive = new ReceivePack(repository)
|
val receive = new ReceivePack(repository)
|
||||||
receive.setPostReceiveHook(new CommitLogHook(owner, repositoryName, user, BaseURL))
|
receive.setPostReceiveHook(new CommitLogHook(owner, repositoryName, user, BaseURL))
|
||||||
Database(context) withTransaction {
|
|
||||||
receive.receive(in, out, err)
|
receive.receive(in, out, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ class PublicKeyAuthenticator(context: ServletContext) extends PublickeyAuthentic
|
|||||||
|
|
||||||
override def authenticate(username: String, key: PublicKey, session: ServerSession): Boolean = {
|
override def authenticate(username: String, key: PublicKey, session: ServerSession): Boolean = {
|
||||||
Database(context) withTransaction {
|
Database(context) withTransaction {
|
||||||
// TODO Check permission to the repository here?
|
|
||||||
getPublicKeys(username).exists { sshKey =>
|
getPublicKeys(username).exists { sshKey =>
|
||||||
str2PublicKey(sshKey.publicKey) match {
|
str2PublicKey(sshKey.publicKey) match {
|
||||||
case Some(publicKey) => key.equals(publicKey)
|
case Some(publicKey) => key.equals(publicKey)
|
||||||
|
|||||||
Reference in New Issue
Block a user