Commit 0378f520 authored by Mathieu's avatar Mathieu

Implements panel users

parent c1a754ec
......@@ -151,7 +151,7 @@ object AdminPanel {
)), aSubRow)
lazy val groupCell: GroupCell = UserPanel.editableData(userName, userEmail, userPassword, userRole, podInfo, userOMVersion, userLastAccess, expanded, editing, (uData: UserData) => save(expandableRow, uData))
lazy val groupCell: GroupCell = UserPanel.editableData(userName, userEmail, userPassword, userRole, podInfo, userOMVersion, userLastAccess, editableEmail = true, editableRole = true, expanded, editing, (uData: UserData) => save(expandableRow, uData))
EmailRow(userEmail, expandableRow)
}
......
package org.openmoleconnect.client
import rx.Rx
import java.nio.ByteBuffer
import org.scalajs.dom
import scala.scalajs.js.annotation.JSExportTopLevel
import boopickle.Default._
import shared.{AdminApi, UserApi}
import autowire._
import rx._
import scaladget.bootstrapnative._
import scaladget.tools.toClass
import scalatags.JsDom.styles
import shared.Data._
import scala.concurrent.ExecutionContext.Implicits.global
import scaladget.bootstrapnative.bsn._
import scaladget.tools._
import scaladget.tools.{ModifierSeq, _}
import scalatags.JsDom.all._
import shared.Data._
import rx._
object UserPanel {
lazy val rowFlex = Seq(styles.display.flex, flexDirection.row, justifyContent.spaceAround)
lazy val columnFlex = Seq(styles.display.flex, flexDirection.column, styles.justifyContent.center, alignItems.flexStart)
lazy val roles = Seq(user, admin)
lazy val roles = Seq(shared.Data.user, shared.Data.admin)
lazy val roleFilter = (r: Role) => r == admin
@JSExportTopLevel("user")
def user(): Unit = {
val currentUser: Var[Option[UserData]] = Var(None)
def getUser =
Post[UserApi].user().call().foreach { u =>
currentUser() = u
}
def upsert(userData: UserData) =
Post[UserApi].upserted(userData).call().foreach { u =>
currentUser() = u
}
lazy val userPanel = div(
Rx {
currentUser().map { uu =>
val panel = editableData(
uu.name,
uu.email,
uu.password,
uu.role,
None,
uu.omVersion,
uu.lastAccess,
editableEmail = false,
editableRole = false,
upserting = (userData: UserData) => upsert(userData)).build
div(maxWidth := 1000, margin := "40px auto")(
img(src := "img/logo.png", css.adminLogoStyle),
Utils.logoutItem(styles.display.flex, flexDirection.row, justifyContent.flexEnd),
div(styles.display.flex, flexDirection.row, justifyContent.flexStart, marginLeft := 50, marginBottom := 20, marginTop := 80)(
// div(width := 350, margin.auto, paddingTop := 200 )(
panel)
)
}.getOrElse(div())
}
)
dom.document.body.appendChild(userPanel)
getUser
}
def editableData(userName: String = "",
userEmail: String = "",
userPassword: String = "",
......@@ -25,9 +80,11 @@ object UserPanel {
podInfo: Option[PodInfo] = None,
userOMVersion: String,
userLastAccess: Long,
editableEmail: Boolean,
editableRole: Boolean,
expanded: Boolean = false,
editing: Boolean = false,
upserting: (UserData) => Unit
upserting: (UserData) => Unit = (u: UserData) => Unit
): GroupCell = {
def roleStyle(s: Role) =
......@@ -35,12 +92,12 @@ object UserPanel {
else label_default
val name = TextCell(userName, Some("Name"), editing)
val email = TextCell(userEmail, Some("Email"), editing)
val email = TextCell(userEmail, Some("Email"), editing, editable = editableEmail)
val password = PasswordCell(userPassword, Some("Password"), editing)
val role = LabelCell(userRole, roles, optionStyle = roleStyle, title = Some("Role"), editing = editing)
val role = LabelCell(userRole, roles, optionStyle = roleStyle, title = Some("Role"), editing = editing, editable = editableRole)
lazy val groupCell: GroupCell = GroupCell(
div(columnFlex, width := "100%")(
div(columnFlex, width := 300)(
name.build(padding := 10),
email.build(padding := 10),
password.build(padding := 10),
......
......@@ -9,13 +9,7 @@ class AdminApiImpl(kubeOff: Boolean) extends shared.AdminApi {
DB.users
}
def upserted(userData: UserData): Seq[UserData] = {
val id = DB.uuid(Email(userData.email)).getOrElse(UUID(java.util.UUID.randomUUID.toString))
upsert(toUser(id, userData))
if (!kubeOff)
K8sService.deployIfNotDeployedYet(id)
users
}
def upserted(userData: UserData): Seq[UserData] = Services.upserted(userData, kubeOff)
def delete(userData: UserData): Seq[UserData] = {
val id = DB.uuid(Email(userData.email))
......
......@@ -24,7 +24,7 @@ import boopickle.Default._
import scala.reflect.ClassTag
import java.nio.ByteBuffer
import scala.concurrent.Await
import scala.concurrent.{Await, Future}
import autowire._
class ConnectServlet(arguments: ConnectServer.ServletArguments) extends ScalatraServlet {
......@@ -32,6 +32,7 @@ class ConnectServlet(arguments: ConnectServer.ServletArguments) extends Scalatra
implicit val secret: JWT.Secret = arguments.secret
val adminApiImpl = new AdminApiImpl(arguments.kubeOff)
val userApiImpl = new UserApiImpl(arguments.kubeOff)
val httpClient = HttpClients.createDefault()
......@@ -86,7 +87,7 @@ class ConnectServlet(arguments: ConnectServer.ServletArguments) extends Scalatra
tokenData.host.hostIP.map { hip =>
getFromHip(hip)
Ok()
}.getOrElse(NotFound())
}.getOrElse(Ok(userHtml))
}
}
}
......@@ -128,30 +129,51 @@ class ConnectServlet(arguments: ConnectServer.ServletArguments) extends Scalatra
}
}
post(s"/${Data.adminRoutePrefix}/*") {
withAdminRights { _ =>
val req = Await.result({
val is = request.getInputStream
val bytes: Array[Byte] = Iterator.continually(is.read()).takeWhile(_ != -1).map(_.asInstanceOf[Byte]).toArray[Byte]
val bb = ByteBuffer.wrap(bytes)
AutowireServer.route[shared.AdminApi](adminApiImpl)(
runRequest(
(bb: ByteBuffer) => AutowireServer.route[shared.AdminApi](adminApiImpl)(
autowire.Core.Request(
Data.adminRoutePrefix.split("/").toSeq ++ multiParams("splat").head.split("/"),
Unpickle[Map[String, ByteBuffer]].fromBytes(bb)
)
)
},
Duration.Inf
)
}
}
val data = Array.ofDim[Byte](req.remaining)
req.get(data)
Ok(data)
post(s"/${Data.userRoutePrefix}/*") {
withAccesToken { tokenData =>
val userData: Option[UserData] = DB.get(tokenData.email)
val userDataByteBuffer = AutowireServer.write(userData)
runRequest(
(bb: ByteBuffer) => AutowireServer.route[shared.UserApi](userApiImpl)(
autowire.Core.Request(
Data.userRoutePrefix.split("/").toSeq ++ multiParams("splat").head.split("/").map{_ + "WithData"},
Unpickle[Map[String, ByteBuffer]].fromBytes(bb) ++ Map("connectedUserData" -> userDataByteBuffer)
)
)
)
}
}
def runRequest(router: ByteBuffer => Future[ByteBuffer]) = {
val req = Await.result({
val is = request.getInputStream
val bytes: Array[Byte] = Iterator.continually(is.read()).takeWhile(_ != -1).map(_.asInstanceOf[Byte]).toArray[Byte]
val bb = ByteBuffer.wrap(bytes)
router(bb)
},
Duration.Inf
)
val data = Array.ofDim[Byte](req.remaining)
req.get(data)
Ok(data)
}
post(Data.connectionRoute) {
Authentication.isValid(request, TokenType.accessToken) match {
case false =>
......@@ -262,6 +284,8 @@ class ConnectServlet(arguments: ConnectServer.ServletArguments) extends Scalatra
def adminHtml = someHtml("admin();")
def userHtml = someHtml("user();")
def someHtml(jsCall: String) = {
contentType = "text/html"
......
......@@ -43,6 +43,10 @@ object DB {
u.lastAccess.value)
}
implicit def optionUserToOptionUserData(auser: Option[User]): Option[UserData] = {
auser.flatMap { u => userToUserData(Seq(u)).headOption }
}
def toUser(uuid: UUID, userData: UserData): User = User(
userData.name,
Email(userData.email),
......@@ -139,9 +143,13 @@ object DB {
_.uuid
}
def uuids = users.map{_.uuid}
def uuids = users.map {
_.uuid
}
def email(uuid: UUID) = users.find(u=> u.uuid == uuid).map{_.email}
def email(uuid: UUID) = users.find(u => u.uuid == uuid).map {
_.email
}
def get(email: Email) = {
runQuery(
......
package org.openmoleconnect.server
import shared.Data.{PodInfo, UserData}
import DB._
object Services {
def upserted(userData: UserData, kubeOff: Boolean): Seq[UserData] = {
val id = DB.uuid (Email (userData.email) ).getOrElse (UUID (java.util.UUID.randomUUID.toString) )
upsert (toUser (id, userData) )
if (! kubeOff)
K8sService.deployIfNotDeployedYet (id)
users
}
}
package org.openmoleconnect.server
import shared.Data.UserData
import shared.UserApi
class UserApiImpl(kubeOff: Boolean) extends UserApi{
def user(): Option[UserData] = None
def userWithData(connectedUserData: Option[UserData]): Option[UserData] = connectedUserData
def upserted(userData: UserData): Option[UserData] = None
def upsertedWithData(userData: UserData, connectedUserData: Option[UserData]): Option[UserData] = {
if(Some(userData.email) == connectedUserData.map{_.email})
Services.upserted(userData, kubeOff)
Some(userData)
}
}
......@@ -3,6 +3,7 @@ package shared
object Data {
val connectionRoute = "/connection"
val adminRoutePrefix = "shared/AdminApi"
val userRoutePrefix = "shared/UserApi"
type Role = String
......
package shared
import shared.Data.UserData
trait UserApi {
def user(): Option[UserData]
def userWithData(connectedUserData: Option[UserData]): Option[UserData]
def upserted(userData: UserData): Option[UserData]
def upsertedWithData(userData: UserData, connectedUserData: Option[UserData]): Option[UserData]
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment