mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-04 20:45:58 +01:00
Add Basic Authentication support for API access
This commit is contained in:
@@ -4,14 +4,14 @@ import javax.servlet._
|
||||
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
|
||||
|
||||
import gitbucket.core.model.Account
|
||||
import gitbucket.core.service.AccessTokenService
|
||||
import gitbucket.core.util.Keys
|
||||
|
||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||
import gitbucket.core.service.{AccessTokenService, AccountService, SystemSettingsService}
|
||||
import gitbucket.core.util.{AuthUtil, Keys}
|
||||
import org.scalatra.servlet.ServletApiImplicits._
|
||||
import org.scalatra._
|
||||
|
||||
|
||||
class AccessTokenAuthenticationFilter extends Filter with AccessTokenService {
|
||||
class AccessTokenAuthenticationFilter extends Filter with AccessTokenService with AccountService with SystemSettingsService {
|
||||
private val tokenHeaderPrefix = "token "
|
||||
|
||||
override def init(filterConfig: FilterConfig): Unit = {}
|
||||
@@ -24,7 +24,7 @@ class AccessTokenAuthenticationFilter extends Filter with AccessTokenService {
|
||||
val response = res.asInstanceOf[HttpServletResponse]
|
||||
Option(request.getHeader("Authorization")).map{
|
||||
case auth if auth.startsWith("token ") => AccessTokenService.getAccountByAccessToken(auth.substring(6).trim).toRight(Unit)
|
||||
// TODO Basic Authentication Support
|
||||
case auth if auth.startsWith("Basic ") => doBasicAuth(auth, loadSystemSettings(), request).toRight(Unit)
|
||||
case _ => Left(Unit)
|
||||
}.orElse{
|
||||
Option(request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]).map(Right(_))
|
||||
@@ -40,4 +40,10 @@ class AccessTokenAuthenticationFilter extends Filter with AccessTokenService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def doBasicAuth(auth: String, settings: SystemSettings, request: HttpServletRequest): Option[Account] = {
|
||||
implicit val session = request.getAttribute(Keys.Request.DBSession).asInstanceOf[slick.jdbc.JdbcBackend#Session]
|
||||
val Array(username, password) = AuthUtil.decodeAuthHeader(auth).split(":", 2)
|
||||
authenticate(settings, username, password)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import javax.servlet.http._
|
||||
import gitbucket.core.plugin.{GitRepositoryFilter, GitRepositoryRouting, PluginRegistry}
|
||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||
import gitbucket.core.service.{RepositoryService, AccountService, SystemSettingsService}
|
||||
import gitbucket.core.util.{Keys, Implicits}
|
||||
import gitbucket.core.util.{Keys, Implicits, AuthUtil}
|
||||
import org.slf4j.LoggerFactory
|
||||
import Implicits._
|
||||
|
||||
@@ -43,7 +43,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
} catch {
|
||||
case ex: Exception => {
|
||||
logger.error("error", ex)
|
||||
requireAuth(response)
|
||||
AuthUtil.requireAuth(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
|
||||
val account = for {
|
||||
auth <- Option(request.getHeader("Authorization"))
|
||||
Array(username, password) = decodeAuthHeader(auth).split(":", 2)
|
||||
Array(username, password) = AuthUtil.decodeAuthHeader(auth).split(":", 2)
|
||||
account <- authenticate(settings, username, password)
|
||||
} yield {
|
||||
request.setAttribute(Keys.Request.UserName, account.userName)
|
||||
@@ -64,7 +64,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
if(filter.filter(request.gitRepositoryPath, account.map(_.userName), settings, isUpdating)){
|
||||
chain.doFilter(request, response)
|
||||
} else {
|
||||
requireAuth(response)
|
||||
AuthUtil.requireAuth(response)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
} else {
|
||||
val passed = for {
|
||||
auth <- Option(request.getHeader("Authorization"))
|
||||
Array(username, password) = decodeAuthHeader(auth).split(":", 2)
|
||||
Array(username, password) = AuthUtil.decodeAuthHeader(auth).split(":", 2)
|
||||
account <- authenticate(settings, username, password)
|
||||
} yield if(isUpdating || repository.repository.isPrivate){
|
||||
if(hasWritePermission(repository.owner, repository.name, Some(account))){
|
||||
@@ -93,7 +93,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
if(passed.getOrElse(false)){
|
||||
chain.doFilter(request, response)
|
||||
} else {
|
||||
requireAuth(response)
|
||||
AuthUtil.requireAuth(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,17 +108,4 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def requireAuth(response: HttpServletResponse): Unit = {
|
||||
response.setHeader("WWW-Authenticate", "BASIC realm=\"GitBucket\"")
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
|
||||
}
|
||||
|
||||
private def decodeAuthHeader(header: String): String = {
|
||||
try {
|
||||
new String(new sun.misc.BASE64Decoder().decodeBuffer(header.substring(6)))
|
||||
} catch {
|
||||
case _: Throwable => ""
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/main/scala/gitbucket/core/util/AuthUtil.scala
Normal file
21
src/main/scala/gitbucket/core/util/AuthUtil.scala
Normal file
@@ -0,0 +1,21 @@
|
||||
package gitbucket.core.util
|
||||
|
||||
import javax.servlet.http.HttpServletResponse
|
||||
|
||||
/**
|
||||
* Provides HTTP (Basic) Authentication related functions.
|
||||
*/
|
||||
object AuthUtil {
|
||||
def requireAuth(response: HttpServletResponse): Unit = {
|
||||
response.setHeader("WWW-Authenticate", "BASIC realm=\"GitBucket\"")
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED)
|
||||
}
|
||||
|
||||
def decodeAuthHeader(header: String): String = {
|
||||
try {
|
||||
new String(new sun.misc.BASE64Decoder().decodeBuffer(header.substring(6)))
|
||||
} catch {
|
||||
case _: Throwable => ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user