Servlet, Filter and Listener are moved to 'servlet' package from 'util'

package.
This commit is contained in:
takezoe
2013-05-07 02:39:48 +09:00
parent 358f59261a
commit 42eded8e2c
5 changed files with 11 additions and 10 deletions

View File

@@ -0,0 +1,118 @@
package servlet
import java.io.File
import java.sql.Connection
import org.apache.commons.io.FileUtils
import javax.servlet.ServletContextEvent
import org.apache.commons.io.IOUtils
import org.slf4j.LoggerFactory
import util.Directory
object AutoUpdate {
/**
* Version of GitBucket
*
* @param majorVersion the major version
* @param minorVersion the minor version
*/
case class Version(majorVersion: Int, minorVersion: Int){
private val logger = LoggerFactory.getLogger(classOf[servlet.AutoUpdate.Version])
/**
* Execute update/MAJOR_MINOR.sql to update schema to this version.
* If corresponding SQL file does not exist, this method do nothing.
*/
def update(conn: Connection): Unit = {
val sqlPath = "update/%d_%d.sql".format(majorVersion, minorVersion)
val in = Thread.currentThread.getContextClassLoader.getResourceAsStream(sqlPath)
if(in != null){
val sql = IOUtils.toString(in, "UTF-8")
val stmt = conn.createStatement()
try {
logger.debug(sqlPath + "=" + sql)
stmt.executeUpdate(sql)
} finally {
stmt.close()
}
}
}
/**
* MAJOR.MINOR
*/
val versionString = "%d.%d".format(majorVersion, minorVersion)
}
/**
* The history of versions. A head of this sequence is the current BitBucket version.
*/
val versions = Seq(
Version(1, 0)
)
/**
* The head version of BitBucket.
*/
val headVersion = versions.head
/**
* The version file (GITBUCKET_HOME/version).
*/
val versionFile = new File(Directory.GitBucketHome, "version")
/**
* Returns the current version from the version file.
*/
def getCurrentVersion(): Version = {
if(versionFile.exists){
FileUtils.readFileToString(versionFile, "UTF-8").split("\\.") match {
case Array(majorVersion, minorVersion) => {
versions.find { v =>
v.majorVersion == majorVersion.toInt && v.minorVersion == minorVersion.toInt
}.getOrElse(Version(0, 0))
}
case _ => Version(0, 0)
}
} else {
Version(0, 0)
}
}
}
/**
* Start H2 database and update schema automatically.
*/
class AutoUpdateListener extends org.h2.server.web.DbStarter {
import AutoUpdate._
private val logger = LoggerFactory.getLogger(classOf[AutoUpdateListener])
override def contextInitialized(event: ServletContextEvent): Unit = {
super.contextInitialized(event)
logger.debug("H2 started")
logger.debug("Start schema update")
val conn = getConnection()
try {
val currentVersion = getCurrentVersion()
if(currentVersion == headVersion){
logger.debug("No update")
} else {
versions.takeWhile(_ != currentVersion).reverse.foreach(_.update(conn))
FileUtils.writeStringToFile(versionFile, headVersion.versionString, "UTF-8")
conn.commit()
logger.debug("Updated from " + currentVersion.versionString + " to " + headVersion.versionString)
}
} catch {
case ex: Throwable => {
logger.error("Failed to schema update", ex)
conn.rollback()
}
}
logger.debug("End schema update")
}
}

View File

@@ -0,0 +1,52 @@
package servlet
import javax.servlet._
import javax.servlet.http._
/**
* Provides BASIC Authentication for [[app.GitRepositoryServlet]].
*/
class BasicAuthenticationFilter extends Filter {
def init(config: FilterConfig) = {}
def destroy(): Unit = {}
def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
val request = req.asInstanceOf[HttpServletRequest]
val response = res.asInstanceOf[HttpServletResponse]
val session = request.getSession
try {
session.getAttribute("USER_INFO") match {
case null => request.getHeader("Authorization") match {
case null => requireAuth(response)
case auth => decodeAuthHeader(auth).split(":") match {
// TODO authenticate using registered user info
case Array(username, password) if(username == "gitbucket" && password == "password") => {
session.setAttribute("USER_INFO", "gitbucket")
chain.doFilter(req, res)
}
case _ => requireAuth(response)
}
}
case user => chain.doFilter(req, res)
}
} catch {
case _: Exception => requireAuth(response)
}
}
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 => ""
}
}
}

View File

@@ -0,0 +1,37 @@
package servlet
import java.io._
import javax.servlet._
import javax.servlet.http._
import org.eclipse.jgit.http.server.GitServlet
import org.slf4j.LoggerFactory
import util.Directory
/**
* Provides Git repository via HTTP.
*
* This servlet provides only Git repository functionality.
* Authentication is provided by [[app.BasicAuthenticationFilter]].
*/
class GitRepositoryServlet extends GitServlet {
private val logger = LoggerFactory.getLogger(classOf[GitRepositoryServlet])
// TODO are there any other ways...?
override def init(config: ServletConfig): Unit = {
super.init(new ServletConfig(){
def getInitParameter(name: String): String = name match {
case "base-path" => Directory.RepositoryHome
case "export-all" => "true"
case name => config.getInitParameter(name)
}
def getInitParameterNames(): java.util.Enumeration[String] = {
config.getInitParameterNames
}
def getServletContext(): ServletContext = config.getServletContext
def getServletName(): String = config.getServletName
});
}
}

View File

@@ -0,0 +1,30 @@
package servlet
import javax.servlet._
import org.slf4j.LoggerFactory
import javax.servlet.http.HttpServletRequest
/**
* Controls the transaction with the open session in view pattern.
*/
class TransactionFilter extends Filter {
private val logger = LoggerFactory.getLogger(classOf[TransactionFilter])
def init(config: FilterConfig) = {}
def destroy(): Unit = {}
def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
if(req.asInstanceOf[HttpServletRequest].getRequestURI().startsWith("/assets/")){
// assets don't need transaction
chain.doFilter(req, res)
} else {
// TODO begin transaction!
logger.debug("TODO begin transaction")
chain.doFilter(req, res)
logger.debug("TODO end transaction")
}
}
}