Skip to content

Commit

Permalink
fix #1760
Browse files Browse the repository at this point in the history
  • Loading branch information
Zwiterrion committed Nov 10, 2023
1 parent f9a4216 commit 3160774
Show file tree
Hide file tree
Showing 18 changed files with 187 additions and 42 deletions.
3 changes: 2 additions & 1 deletion experiments/common-wasm/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ lazy val scala213 = "2.13.11"
lazy val supportedScalaVersions = List(scala212, scala213)

ThisBuild / scalaVersion := scala212
ThisBuild / version := "16.11.0-dev"
ThisBuild / version := "16.11.1-dev"
ThisBuild / organization := "io.otoroshi.common"
ThisBuild / organizationName := "wasm"

Expand Down Expand Up @@ -68,6 +68,7 @@ lazy val root = (project in file("."))
"com.typesafe.akka" %% "akka-stream" % akkaVersion % "provided",
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion % "provided",
"com.typesafe.play" %% "play-json-joda" % playJsonVersion % "provided",
"com.auth0" % "java-jwt" % "4.2.0" excludeAll (excludesJackson: _*),
"commons-codec" % "commons-codec" % "1.16.0" % "provided",
"net.java.dev.jna" % "jna" % "5.13.0" % "provided",
"com.google.code.gson" % "gson" % "2.10" % "provided",
Expand Down
Empty file modified experiments/common-wasm/build.sh
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.otoroshi.common.wasm.scaladsl

import com.auth0.jwt.algorithms.Algorithm
import play.api.libs.json.{JsObject, Json}

import java.nio.charset.StandardCharsets

object ApikeyHelper {

def generate(settings: WasmManagerSettings): String = {
val header = Json.obj(
"typ" -> "JWT",
"alg" -> "HS512"
)
val payload = Json.obj(
"iss" -> "otoroshi"
)
sign(header, payload, settings.tokenSecret.getOrElse(""))
}

private def sign(headerJson: JsObject, payloadJson: JsObject, tokenSecret: String): String = {
val header: String = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(Json.toBytes(headerJson))
val payload: String = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(Json.toBytes(payloadJson))
val signatureBytes: Array[Byte] =
Algorithm.HMAC512(tokenSecret).sign(header.getBytes(StandardCharsets.UTF_8), payload.getBytes(StandardCharsets.UTF_8))

val signature: String = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(signatureBytes)
String.format("%s.%s.%s", header, payload, signature)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ case class WasmManagerSettings(
url: String = "http://localhost:5001",
clientId: String = "admin-api-apikey-id",
clientSecret: String = "admin-api-apikey-secret",
pluginsFilter: Option[String] = Some("*")
pluginsFilter: Option[String] = Some("*"),
tokenSecret: Option[String] = Some("secret")
) {
def json: JsValue = WasmManagerSettings.format.writes(this)
}
Expand All @@ -21,7 +22,8 @@ object WasmManagerSettings {
"url" -> o.url,
"clientId" -> o.clientId,
"clientSecret" -> o.clientSecret,
"pluginsFilter" -> o.pluginsFilter.map(JsString).getOrElse(JsNull).as[JsValue]
"pluginsFilter" -> o.pluginsFilter.map(JsString).getOrElse(JsNull).as[JsValue],
"tokenSecret" -> o.tokenSecret.map(JsString).getOrElse(JsNull).as[JsValue]
)

override def reads(json: JsValue): JsResult[WasmManagerSettings] =
Expand All @@ -30,7 +32,8 @@ object WasmManagerSettings {
url = (json \ "url").asOpt[String].getOrElse("http://localhost:5001"),
clientId = (json \ "clientId").asOpt[String].getOrElse("admin-api-apikey-id"),
clientSecret = (json \ "clientSecret").asOpt[String].getOrElse("admin-api-apikey-secret"),
pluginsFilter = (json \ "pluginsFilter").asOpt[String].getOrElse("*").some
pluginsFilter = (json \ "pluginsFilter").asOpt[String].getOrElse("*").some,
tokenSecret = (json \ "tokenSecret").asOpt[String].getOrElse("secret").some,
)
} match {
case Failure(e) => JsError(e.getMessage)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,16 @@ object WasmSourceKind {
ec: ExecutionContext
): Future[Either[JsValue, ByteString]] = {
ic.wasmManagerSettings.flatMap {
case Some(WasmManagerSettings(url, clientId, clientSecret, kind)) => {
case Some(settings @ WasmManagerSettings(url, clientId, clientSecret, kind, tokenSecret)) => {
val apikey = ApikeyHelper
.generate(settings)
ic.url(s"$url/wasm/$path")
.withFollowRedirects(false)
.withRequestTimeout(FiniteDuration(5 * 1000, MILLISECONDS))
.withHttpHeaders(
"Accept" -> "application/json",
"Otoroshi-Client-Id" -> clientId,
"Otoroshi-Client-Secret" -> clientSecret,
"kind" -> kind.getOrElse("*")
"Accept" -> "application/json",
"Otoroshi-User" -> apikey,
"kind" -> kind.getOrElse("*")
)
.get()
.flatMap { resp =>
Expand Down Expand Up @@ -272,6 +273,7 @@ object WasmSourceKind {
case "base64" => Base64
case "http" => Http
case "wasmmanager" => WasmManager
case "wasmo" => WasmManager
case "local" => Local
case "file" => File
case _ => Unknown
Expand Down
Empty file modified experiments/common-wasm/update-extism.sh
100644 → 100755
Empty file.
41 changes: 37 additions & 4 deletions otoroshi/app/controllers/BackOfficeController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import otoroshi.ssl._
import otoroshi.ssl.pki.models.{GenCertResponse, GenCsrQuery}
import otoroshi.utils.http.MtlsConfig
import otoroshi.utils.http.RequestImplicits._
import otoroshi.utils.infotoken.InfoTokenHelper
import otoroshi.utils.syntax.implicits._
import otoroshi.utils.yaml.Yaml
import play.api.Logger
Expand Down Expand Up @@ -1979,22 +1980,22 @@ class BackOfficeController(
.singleton()
.flatMap { globalConfig =>
globalConfig.wasmManagerSettings match {
case Some(WasmManagerSettings(url, clientId, clientSecret, pluginsFilter)) =>
case Some(settings @ WasmManagerSettings(url, _, _, pluginsFilter, _)) =>
val claim = ApikeyHelper.generate(settings)
Try {
env.Ws
.url(s"$url/plugins")
.withFollowRedirects(false)
.withHttpHeaders(
"Otoroshi-Client-Id" -> clientId,
"Otoroshi-Client-Secret" -> clientSecret,
"Otoroshi-User" -> claim,
"kind" -> pluginsFilter.getOrElse("*")
)
.get()
.map(res => {
if (res.status == 200) {
Ok(res.json)
} else {
Ok(Json.arr())
BadRequest("Unable to join the wasmo server")
}
})
.recover { case e: Throwable =>
Expand All @@ -2015,6 +2016,38 @@ class BackOfficeController(
}
}

def getWasmFilesFromBodyConfiguration() = BackOfficeActionAuth.async(parse.json) { ctx =>
val jsonBody = ctx.request.body

val wasmoSettings = WasmManagerSettings.format.reads(jsonBody).get
val apikey = ApikeyHelper.generate(wasmoSettings)

Try {
env.Ws
.url(s"${wasmoSettings.url}/plugins")
.withFollowRedirects(false)
.withHttpHeaders(
"Otoroshi-User" -> apikey,
"kind" -> wasmoSettings.pluginsFilter.getOrElse("*")
)
.get()
.map(res => {
if (res.status == 200) {
Ok(res.json)
} else {
BadRequest("Unable to join the wasmo server")
}
})
.recover { case e: Throwable =>
logger.error(e.getMessage)
Ok(Json.arr())
}
} match {
case Failure(err) => Ok(Json.arr()).vfuture
case Success(v) => v
}
}

def anonymousReporting() = BackOfficeActionAuth.async(parse.json) { ctx =>
val enabled = ctx.request.body.select("enabled").asOpt[Boolean].getOrElse(false)
if (enabled) {
Expand Down
1 change: 1 addition & 0 deletions otoroshi/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ POST /bo/api/graphql_to_json otoroshi.controlle
POST /bo/api/json_to_graphql_schema otoroshi.controllers.BackOfficeController.jsonToGraphqlSchema()
POST /bo/api/json_to_yaml otoroshi.controllers.BackOfficeController.toYaml()
GET /bo/api/plugins/wasm otoroshi.controllers.BackOfficeController.wasmFiles()
POST /bo/api/plugins/wasm otoroshi.controllers.BackOfficeController.getWasmFilesFromBodyConfiguration()
GET /bo/api/test_match_and_project_input otoroshi.controllers.BackOfficeController.testFilteringAndProjectionInputDoc()
POST /bo/api/test_match_and_project otoroshi.controllers.BackOfficeController.testFilteringAndProjection()

Expand Down
8 changes: 2 additions & 6 deletions otoroshi/javascript/src/components/Toasts.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,31 @@ class Toast extends Component {
marginBottom: 10,
width: '100%',
backgroundColor,
height: 140,
border: '1px solid #444',
borderRadius: '5px',
}}>
<div
style={{
fontWeight: 'bold',
color,
width: '100%',
height: 40,
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
borderBottom: '1px solid #444',
}}>
{this.props.toast.title}{' '}
<button
type="button"
className="btn btn-sm btn-danger"
onClick={(e) => this.props.close()}>
X
<i className='fas fa-times' style={{ color: '#fff' }} />
</button>
</div>
<div
style={{
width: '100%',
height: 80,
display: 'flex',
color: 'var(--color_level3)',
fontSize: '1rem',
flexDirection: 'column',
marginTop: '10px',
}}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ export class ReactSelectOverride extends React.Component {
(o) => o === this.props.value || (isOptionObject ? o.value === this.props.value : false)
);

console.log(opt, this.props)

if (!opt)
return undefined

Expand Down
3 changes: 2 additions & 1 deletion otoroshi/javascript/src/components/nginputs/inputs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,7 @@ export class NgSelectRenderer extends Component {
render() {
const schema = this.props.schema || {};
const props = schema.props || this.props || {};
const formatValue = props.formatValue;
const readOnly = this.props.readOnly;
const creatable = this.state.creatable || props.creatable || this.props.creatable;

Expand All @@ -1169,7 +1170,7 @@ export class NgSelectRenderer extends Component {
<ReactSelectOverride
name={`selector-${this.props.name}`}
creatable={creatable}
value={this.props.value}
value={formatValue ? formatValue(this.props.value) : this.props.value}
isMulti={props.isMulti}
isLoading={this.state.loading}
disabled={props.disabled}
Expand Down
5 changes: 3 additions & 2 deletions otoroshi/javascript/src/components/window.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Alert extends Component {
return (
<div className="modal" tabIndex="-1" role="dialog" style={{ display: 'block' }}>
<div className="modal-dialog" role="document" style={this.props.modalStyleOverride || {}}>
<div className="modal-content">
<div className="modal-content" style={this.props.contentStyleOverride || {}}>
<div className="modal-header">
<h4 className="modal-title">{this.props.title ? this.props.title : 'Alert'}</h4>
<button
Expand Down Expand Up @@ -202,13 +202,14 @@ export function registerAlert() {
div.setAttribute('id', 'otoroshi-alerts-container');
document.body.appendChild(div);
}
window.newAlert = (message, title, linkOpt, modalStyleOverride = {}) => {
window.newAlert = (message, title, linkOpt, modalStyleOverride = {}, contentStyleOverride = {}) => {
return new Promise((success) => {
ReactDOM.render(
<Alert
message={message}
title={title}
linkOpt={linkOpt}
contentStyleOverride={contentStyleOverride}
modalStyleOverride={modalStyleOverride}
close={() => {
ReactDOM.unmountComponentAtNode(document.getElementById('otoroshi-alerts-container'));
Expand Down
2 changes: 1 addition & 1 deletion otoroshi/javascript/src/forms/ng_plugins/WasmOPA.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default {
type: 'select',
props: {
label: 'Kind',
options: ['Base64', 'Http', 'WasmManager', 'Local', 'File'].map((v) => ({
options: ['Base64', 'Http', 'Wasmo', 'Local', 'File'].map((v) => ({
label: v,
value: v.toLowerCase(),
})),
Expand Down
7 changes: 6 additions & 1 deletion otoroshi/javascript/src/forms/ng_plugins/WasmPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ const schema = {
label: 'Kind',
type: 'select',
props: {
formatValue: value => {
if (value === "wasmmanager")
return "wasmo"
return value
},
label: 'Kind',
options: ['Base64', 'Http', 'WasmManager', 'Local', 'File'].map((v) => ({
options: ['Base64', 'Http', 'Wasmo', 'Local', 'File'].map((v) => ({
label: v,
value: v.toLowerCase(),
})),
Expand Down
Loading

0 comments on commit 3160774

Please sign in to comment.