Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit b485e15

Browse files
authored
Merge pull request #1 from codeoverflow-org/master
Merge master
2 parents ba3cbc7 + 45dacb8 commit b485e15

15 files changed

+392
-304
lines changed

src/main/scala/ScalatraBootstrap.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ class ScalatraBootstrap extends LifeCycle {
1414
implicit val swagger: CodeOverflowSwagger = new CodeOverflowSwagger(apiVersion)
1515

1616
override def init(context: ServletContext) {
17+
1718
// Allow CORS
1819
context.initParameters("org.scalatra.cors.allowedOrigins") = "*"
1920
context.initParameters("org.scalatra.cors.allowCredentials") = "false"
21+
context.initParameters("org.scalatra.cors.allowedMethods") = "*"
2022

2123
// Add all servlets and controller
2224
context.mount(new TypeController(), "/types/*", "types")

src/main/scala/org/codeoverflow/chatoverflow/framework/manager/PluginManagerImpl.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import scala.collection.mutable.ListBuffer
1515
*/
1616
class PluginManagerImpl(pluginInstanceName: String, logOutputOnConsole: Boolean) extends PluginManager with WithLogger {
1717

18+
// TODO: Add log datetime
1819
private val logMessages = new ListBuffer[String]
1920

2021
/**

src/main/scala/org/codeoverflow/chatoverflow/ui/CLI.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ object CLI {
7575
case class Config(pluginFolderPath: String = "plugins/",
7676
configFolderPath: String = "config/",
7777
requirementPackage: String = "org.codeoverflow.chatoverflow.requirement",
78-
ui: UI = UI.BOTH,
78+
ui: UI = UI.GUI,
7979
requirePasswordOnStartup: Boolean = true,
8080
pluginDataPath: String = "data",
8181
webServerPort: Int = 2400,

src/main/scala/org/codeoverflow/chatoverflow/ui/web/JsonServlet.scala

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import org.codeoverflow.chatoverflow.ui.web.rest.DTOs.ResultMessage
55
import org.codeoverflow.chatoverflow.{ChatOverflow, Launcher}
66
import org.json4s.{DefaultFormats, Formats}
77
import org.scalatra.json.JacksonJsonSupport
8-
import org.scalatra.{CorsSupport, ScalatraServlet}
8+
import org.scalatra.{BadRequest, CorsSupport, ScalatraServlet, Unauthorized}
99

1010
/**
1111
* A Json Servlet enables implicit json conversion for servlet output.
@@ -19,6 +19,14 @@ abstract class JsonServlet extends ScalatraServlet with JacksonJsonSupport with
1919
contentType = formats("json")
2020
}
2121

22+
// CORS support (preflight requests)
23+
options("/*") {
24+
response.setHeader(
25+
"Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"))
26+
response.setHeader(
27+
"Access-Control-Allow-Methods", request.getHeader("Access-Control-Request-Method"))
28+
}
29+
2230
/**
2331
* Utility function to parse incoming json-body-arguments. Uses a lot of scala magic. Magical!
2432
*
@@ -45,4 +53,23 @@ abstract class JsonServlet extends ScalatraServlet with JacksonJsonSupport with
4553
}
4654
}
4755
}
56+
57+
/**
58+
* Utility function to test the authKey-existence in header first.
59+
*
60+
* @param func the function to execute, if the authorization was successful
61+
* @param request the request, implicitly provided by the scalatra environment
62+
* @return the result of the provided func or an http error if the auth key is wrong
63+
*/
64+
protected def authKeyRequired(func: => Any)(implicit request: HttpServletRequest): Any = {
65+
val authKeyKey = "authKey"
66+
67+
if (request.header(authKeyKey).isEmpty) {
68+
BadRequest()
69+
} else if (request.header(authKeyKey).get != chatOverflow.credentialsService.generateAuthKey()) {
70+
Unauthorized()
71+
} else {
72+
func
73+
}
74+
}
4875
}

src/main/scala/org/codeoverflow/chatoverflow/ui/web/Server.scala

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package org.codeoverflow.chatoverflow.ui.web
22

3-
import java.awt.Desktop
4-
import java.net.URL
5-
63
import org.codeoverflow.chatoverflow.{ChatOverflow, WithLogger}
74
import org.eclipse.jetty.servlet.ServletHandler.Default404Servlet
85
import org.eclipse.jetty.webapp.WebAppContext
@@ -33,13 +30,8 @@ class Server(val chatOverflow: ChatOverflow, val port: Int) extends WithLogger {
3330
// TODO: Enable shutting down the server
3431
new Thread(() => startServer()).start()
3532

36-
// TODO: Replace this with the proper GUI, when available
37-
try {
38-
val petstoreURL = s"http://petstore.swagger.io/?url=http://localhost:$port/api-docs/swagger.json"
39-
Desktop.getDesktop.browse(new URL(petstoreURL).toURI)
40-
} catch {
41-
case _: Exception => logger debug "Unable to open GUI in browser."
42-
}
33+
println(s"You may open now: http://petstore.swagger.io/?url=http://localhost:$port/api-docs/swagger.json")
34+
println("Or try out the new gui: http://localhost:2400")
4335
}
4436

4537
private def startServer(): Unit = {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.codeoverflow.chatoverflow.ui.web.rest
2+
3+
import org.scalatra.swagger.{SwaggerSupport, SwaggerSupportSyntax}
4+
5+
trait AuthSupport extends SwaggerSupport {
6+
7+
protected def authHeader: SwaggerSupportSyntax.ParameterBuilder[String] =
8+
headerParam[String]("authKey").description("connection auth key required")
9+
10+
}

src/main/scala/org/codeoverflow/chatoverflow/ui/web/rest/DTOs.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,4 @@ object DTOs {
4343

4444
case class Password(password: String)
4545

46-
case class AuthKey(authKey: String)
47-
4846
}

src/main/scala/org/codeoverflow/chatoverflow/ui/web/rest/config/ConfigController.scala

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.codeoverflow.chatoverflow.Launcher
44
import org.codeoverflow.chatoverflow.api.APIVersion
55
import org.codeoverflow.chatoverflow.configuration.CryptoUtil
66
import org.codeoverflow.chatoverflow.ui.web.JsonServlet
7-
import org.codeoverflow.chatoverflow.ui.web.rest.DTOs.{AuthKey, ConfigInfo, Password, ResultMessage}
7+
import org.codeoverflow.chatoverflow.ui.web.rest.DTOs.{ConfigInfo, Password, ResultMessage}
88
import org.scalatra.swagger._
99

1010
class ConfigController(implicit val swagger: Swagger) extends JsonServlet with ConfigControllerDefinition {
@@ -16,29 +16,25 @@ class ConfigController(implicit val swagger: Swagger) extends JsonServlet with C
1616
}
1717

1818
post("/save", operation(postSave)) {
19-
if (!chatOverflow.isLoaded) {
20-
false
21-
} else {
22-
chatOverflow.save()
23-
true
19+
authKeyRequired {
20+
if (!chatOverflow.isLoaded) {
21+
false
22+
} else {
23+
chatOverflow.save()
24+
true
25+
}
2426
}
2527
}
2628

2729
// Is this even a thing?
2830
post("/exit", operation(postExit)) {
29-
parsedAs[AuthKey] {
30-
case AuthKey(authKey) =>
31-
if (authKey != chatOverflow.credentialsService.generateAuthKey()) {
32-
ResultMessage(success = false, "Wrong auth key.")
33-
34-
} else {
35-
// Give enough time to return success. Then bye bye
36-
new Thread(() => {
37-
Thread.sleep(500)
38-
Launcher.exit()
39-
}).start()
40-
ResultMessage(success = true)
41-
}
31+
authKeyRequired {
32+
// Give enough time to return success. Then bye bye
33+
new Thread(() => {
34+
Thread.sleep(500)
35+
Launcher.exit()
36+
}).start()
37+
ResultMessage(success = true)
4238
}
4339
}
4440

src/main/scala/org/codeoverflow/chatoverflow/ui/web/rest/config/ConfigControllerDefinition.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package org.codeoverflow.chatoverflow.ui.web.rest.config
22

3-
import org.codeoverflow.chatoverflow.ui.web.rest.DTOs.{AuthKey, ConfigInfo, Password, ResultMessage}
4-
import org.codeoverflow.chatoverflow.ui.web.rest.TagSupport
3+
import org.codeoverflow.chatoverflow.ui.web.rest.DTOs.{ConfigInfo, Password, ResultMessage}
4+
import org.codeoverflow.chatoverflow.ui.web.rest.{AuthSupport, TagSupport}
55
import org.scalatra.swagger.SwaggerSupport
66
import org.scalatra.swagger.SwaggerSupportSyntax.OperationBuilder
77

8-
trait ConfigControllerDefinition extends SwaggerSupport with TagSupport {
8+
trait ConfigControllerDefinition extends SwaggerSupport with TagSupport with AuthSupport {
99

1010
val getConfig: OperationBuilder =
1111
(apiOperation[ConfigInfo]("getConfig")
@@ -16,13 +16,14 @@ trait ConfigControllerDefinition extends SwaggerSupport with TagSupport {
1616
(apiOperation[Boolean]("postSave")
1717
summary "Triggers the saving process of the framework manually (if loaded previously)."
1818
description "Triggers saving of credentials and configuration. Should not be needed manually."
19+
parameter authHeader
1920
tags controllerTag)
2021
val postExit: OperationBuilder =
2122
(apiOperation[ResultMessage]("postExit")
2223
summary "Shuts the framework down."
2324
description "Shutdown the framework in the next second if a correct auth key is supplied."
24-
tags controllerTag
25-
parameter bodyParam[AuthKey]("body").description("Requires the run specific auth key."))
25+
parameter authHeader
26+
tags controllerTag)
2627
val getLogin: OperationBuilder =
2728
(apiOperation[Boolean]("getLogin")
2829
summary "Returns if the framework is already loaded."

0 commit comments

Comments
 (0)