5
5
6
6
package org .scalaexercises .evaluator
7
7
8
+ import com .typesafe .config .ConfigFactory
8
9
import io .circe .Decoder
9
10
import monix .execution .Scheduler
10
11
import org .http4s ._
11
12
import org .http4s .dsl ._
12
13
import org .http4s .server .blaze ._
13
14
import org .log4s .getLogger
14
15
16
+ import scala .collection .JavaConversions ._
15
17
import scala .concurrent .duration ._
16
18
import scala .language .postfixOps
17
19
@@ -23,6 +25,17 @@ object services {
23
25
24
26
private val logger = getLogger
25
27
28
+ val config = ConfigFactory .load()
29
+
30
+ val AllowedCompilerFlags = " allowed.compiler.flags"
31
+
32
+ val allowedCompilerFlags = if (config.hasPath(AllowedCompilerFlags )) {
33
+ config.getStringList(AllowedCompilerFlags ).toList
34
+ } else {
35
+ throw new IllegalStateException (
36
+ " Missing -D allowed.compiler.flags=[YOUR_KEY_HERE] or env var [ALLOWED_COMPILER_FLAGS]" )
37
+ }
38
+
26
39
implicit val scheduler : Scheduler = Scheduler .io(" scala-evaluator" )
27
40
28
41
val evaluator = new Evaluator (20 seconds)
@@ -68,45 +81,52 @@ object services {
68
81
req
69
82
.decodeWith[EvalRequest ](decoder, strict = false ) {
70
83
evalRequest =>
71
- evaluator.eval[Any ](
72
- code = evalRequest.code,
73
- remotes = evalRequest.resolvers,
74
- dependencies = evalRequest.dependencies,
75
- compilerFlags = evalRequest.compilerFlags
76
- ) flatMap {
77
- (result : EvalResult [_]) =>
78
- val response = result match {
79
- case EvalSuccess (cis, res, out) =>
80
- EvalResponse (
81
- `ok`,
82
- Option (res.toString),
83
- Option (res.asInstanceOf [AnyRef ].getClass.getName),
84
- cis)
85
- case Timeout (_) =>
86
- EvalResponse (`Timeout Exceded`, None , None , Map .empty)
87
- case UnresolvedDependency (msg) =>
88
- EvalResponse (
89
- `Unresolved Dependency` + " : " + msg,
90
- None ,
91
- None ,
92
- Map .empty)
93
- case EvalRuntimeError (cis, runtimeError) =>
94
- EvalResponse (
95
- `Runtime Error`,
96
- runtimeError map (_.error.getMessage),
97
- runtimeError map (_.error.getClass.getName),
98
- cis)
99
- case CompilationError (cis) =>
100
- EvalResponse (`Compilation Error`, None , None , cis)
101
- case GeneralError (err) =>
102
- EvalResponse (
103
- `Unforeseen Exception`,
104
- None ,
105
- None ,
106
- Map .empty)
107
- }
108
- Ok (response.asJson)
109
- }
84
+ val (validCompilerFlags, invalidCompilerFlags) =
85
+ evalRequest.compilerFlags.partition(
86
+ allowedCompilerFlags.contains(_))
87
+ if (invalidCompilerFlags.isEmpty) {
88
+ evaluator.eval[Any ](
89
+ code = evalRequest.code,
90
+ remotes = evalRequest.resolvers,
91
+ dependencies = evalRequest.dependencies,
92
+ compilerFlags = validCompilerFlags
93
+ ) flatMap {
94
+ (result : EvalResult [_]) =>
95
+ val response = result match {
96
+ case EvalSuccess (cis, res, out) =>
97
+ EvalResponse (
98
+ `ok`,
99
+ Option (res.toString),
100
+ Option (res.asInstanceOf [AnyRef ].getClass.getName),
101
+ cis)
102
+ case Timeout (_) =>
103
+ EvalResponse (`Timeout Exceded`, None , None , Map .empty)
104
+ case UnresolvedDependency (msg) =>
105
+ EvalResponse (
106
+ `Unresolved Dependency` + " : " + msg,
107
+ None ,
108
+ None ,
109
+ Map .empty)
110
+ case EvalRuntimeError (cis, runtimeError) =>
111
+ EvalResponse (
112
+ `Runtime Error`,
113
+ runtimeError map (_.error.getMessage),
114
+ runtimeError map (_.error.getClass.getName),
115
+ cis)
116
+ case CompilationError (cis) =>
117
+ EvalResponse (`Compilation Error`, None , None , cis)
118
+ case GeneralError (err) =>
119
+ EvalResponse (
120
+ `Unforeseen Exception`,
121
+ None ,
122
+ None ,
123
+ Map .empty)
124
+ }
125
+ Ok (response.asJson)
126
+ }
127
+ } else
128
+ BadRequest (
129
+ s " Invalid compiler flags: ${invalidCompilerFlags.mkString(" ," )}" )
110
130
}
111
131
.map((r : Response ) => r.putHeaders(corsHeaders : _* ))
112
132
})
0 commit comments