Commit 69a7f0dd authored by Mathieu's avatar Mathieu

Implement user lastAccess mechanism

parent a878876e
......@@ -43,6 +43,6 @@ object Application extends App {
server.start()
}
DB.addUser("Moo",DB.Email("moo@moo.com"), DB.Password("moo"), DB.simpleUser)
DB.addUser("Moo",DB.Email("moo@moo.com"), DB.Password("moo"), Utils.openmoleversion.stable, 900009870L, DB.simpleUser)
}
......@@ -18,19 +18,19 @@ import shared.Data._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.scalajs.js.typedarray.{ArrayBuffer, TypedArrayBuffer}
import scaladget.bootstrapnative.bsn._
import scaladget.tools._
import scalatags.JsDom.all._
import scala.scalajs.js.Date
object AdminPanel {
@JSExportTopLevel("admin")
def admin() = {
implicit def userDataSeqToRows(userData: Seq[UserData]): Seq[ExpandableRow] = userData.map { u =>
buildExpandable(u.name, u.email, u.password, u.role, running)
buildExpandable(u.name, u.email, u.password, u.role, u.omVersion, u.lastAccess, running)
}
......@@ -54,6 +54,11 @@ object AdminPanel {
rows() = _
}
def delete(userData: UserData) =
Post[AdminApi].delete(userData).call().foreach {
rows() = _
}
def closeAll(except: ExpandableRow) = rows.now.filterNot {
_ == except
......@@ -62,12 +67,29 @@ object AdminPanel {
}
def buildExpandable(userName: String = "", userEmail: String = "", userPassword: String = "", userRole: Role = "", userStatus: Status = user, expanded: Boolean = false): ExpandableRow = {
def buildExpandable(userName: String = "",
userEmail: String = "",
userPassword: String = "",
userRole: Role = "",
userOMVersion: String = "",
userLastAccess: Long = 0L,
userStatus: Status = user,
expanded: Boolean = false): ExpandableRow = {
val aVar = Var(expanded)
val lastAccess = new Date(userLastAccess.toDouble)
lazy val aSubRow: StaticSubRow = StaticSubRow({
div(height := 120, rowFlex)(
div(height := 300, rowFlex)(
groupCell.build(margin := 25),
label(label_primary, userOMVersion),
div(lastAccess.toUTCString), //.formatted("EEE, d MMM yyyy HH:mm:ss"),
span(columnFlex, alignItems.flexEnd, justifyContent.flexEnd)(
button(btn_danger, "Delete", onclick := { () =>
val userData = UserData(userName, userEmail, userPassword, userRole, userOMVersion, userLastAccess)
delete(userData)
}, margin := 10)
)
)
}, aVar)
......@@ -85,7 +107,7 @@ object AdminPanel {
)), aSubRow)
lazy val groupCell: GroupCell = UserPanel.editableData(userName, userEmail, userPassword, userRole, userStatus, expanded, (uData: UserData)=> save(expandableRow, uData))
lazy val groupCell: GroupCell = UserPanel.editableData(userName, userEmail, userPassword, userRole, userStatus, userOMVersion, userLastAccess, expanded, (uData: UserData) => save(expandableRow, uData))
expandableRow
}
......
......@@ -12,8 +12,8 @@ import rx._
object UserPanel {
lazy val rowFlex = Seq(styles.display.flex, flexDirection.row, justifyContent.spaceAround, alignItems.center)
lazy val columnFlex = Seq(styles.display.flex, flexDirection.column, styles.justifyContent.center)
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, shared.Data.admin)
lazy val roleFilter = (r: Role) => r == shared.Data.admin
......@@ -23,9 +23,11 @@ object UserPanel {
userPassword: String = "",
userRole: Role = "",
userStatus: Status = user,
userOMVersion: String,
userLastAccess: Long,
expanded: Boolean = false,
upserting: (UserData) => Unit): GroupCell = {
val aVar = Var(expanded)
upserting: (UserData) => Unit
): GroupCell = {
def roleStyle(s: Role) =
if (s == shared.Data.admin) label_success
......@@ -38,34 +40,29 @@ object UserPanel {
val rowEdit = Var(false)
val buttonStyle: ModifierSeq = Seq(
fontSize := 22,
color := "#23527c",
opacity := 0.8
)
lazy val groupCell: GroupCell = GroupCell(
div(rowFlex, width := "100%")(
div(columnFlex, width := "100%")(
name.build(padding := 10),
email.build(padding := 10),
password.build(padding := 10),
role.build(padding := 10),
span(
span(rowFlex, marginTop := 50)(
Rx {
if (rowEdit()) glyphSpan(glyph_save +++ buttonStyle +++ toClass("actionIcon"), () => {
if (rowEdit()) button(btn_primary, "Save", onclick := { () =>
val userRole: Role = role.get
val modifiedUser = UserData(name.get, email.get, password.get, userRole)
val modifiedUser = UserData(name.get, email.get, password.get, userRole, userOMVersion, userLastAccess)
upserting(modifiedUser)
rowEdit.update(!rowEdit.now)
})
else glyphSpan(glyph_edit2 +++ buttonStyle +++ toClass("actionIcon"), () => {
else button(btn_default, "Edit", onclick := { () =>
//button("Edit", btn_default, onclick := { () =>
rowEdit.update(!rowEdit.now)
groupCell.switch
})
}
)
), name, email, password, role)
)),
name, email, password, role
)
groupCell
}
......
......@@ -15,4 +15,11 @@ object AdminApiImpl extends shared.AdminApi {
users
}
def delete(userData: UserData): Seq[UserData] = {
val id = DB.uuid(Email(userData.email))
id.foreach {i=>
DB.delete(toUser(i, userData))
}
users
}
}
\ No newline at end of file
......@@ -166,6 +166,9 @@ class ConnectServlet(arguments: ConnectServer.ServletArguments) extends Scalatra
val host = Host(uuid, None)
buildAndAddCookieToHeader(TokenData.accessToken(host, DB.Email(email)))
buildAndAddCookieToHeader(TokenData.refreshToken(host, DB.Email(email)))
println("SET Last access")
DB.setLastAccess(DB.Email(email), JWT.now)
println("ACSS ? " + DB.get(DB.Email(email)).map{_.lastAccess})
redirect("/")
case _ => Ok(connectionHtml)
}
......
......@@ -10,10 +10,13 @@ import scala.concurrent.ExecutionContext.Implicits.global
import slick.jdbc.H2Profile.api._
import DBQueries._
import shared._
import slick.model.ForeignKey
object DB {
// USERS
case class UUID(value: String) extends MappedTo[String]
case class Email(value: String) extends MappedTo[String]
......@@ -22,16 +25,33 @@ object DB {
case class Role(value: String) extends MappedTo[String]
case class Version(value: String) extends MappedTo[String]
val admin = Role("admin")
val simpleUser = Role("simpleUser")
case class User(name: String, email: Email, password: Password, role: Role = simpleUser, uuid: UUID = UUID(""))
implicit def userToUserData(users: Seq[User]): Seq[Data.UserData] = users.map { u => Data.UserData(u.name.value, u.email.value, u.password.value, u.role.value) }
def toUser(uuid: UUID, userData: UserData): User = User(userData.name, Email(userData.email), Password(userData.password), Role(userData.role), uuid)
case class User(name: String, email: Email, password: Password, omVersion: Version, lastAccess: Long, role: Role = simpleUser, uuid: UUID = UUID(""))
implicit def userToUserData(users: Seq[User]): Seq[Data.UserData] = users.map { u =>
Data.UserData(
u.name.value,
u.email.value,
u.password.value,
u.role.value,
u.omVersion.value,
u.lastAccess.value) }
def toUser(uuid: UUID, userData: UserData): User = User(
userData.name,
Email(userData.email),
Password(userData.password),
Version(userData.omVersion),
userData.lastAccess,
Role(userData.role),
uuid
)
class Users(tag: Tag) extends Table[(UUID, String, Email, Password, Role)](tag, "USERS") {
class Users(tag: Tag) extends Table[(UUID, String, Email, Password, Role, Version, Long)](tag, "USERS") {
def uuid = column[UUID]("UUID", O.PrimaryKey)
def name = column[String]("NAME")
......@@ -42,7 +62,12 @@ object DB {
def role = column[Role]("ROLE")
def * = (uuid, name, email, password, role)
def omVersion = column[Version]("OMVERSION")
def lastAccess = column[Long]("LASTACCESS")
def * = (uuid, name, email, password, role, omVersion, lastAccess)
}
val userTable = TableQuery[Users]
......@@ -63,25 +88,38 @@ object DB {
def initDB = {
runTransaction(userTable.schema.createIfNotExists)
if (DB.users.isEmpty) {
DB.addUser("admin", DB.Email("admin@admin.com"), DB.Password("admin"), DB.admin, UUID("foo-123-567-foo"))
DB.addUser("admin", DB.Email("admin@admin.com"), DB.Password("admin"), Utils.openmoleversion.stable, JWT.now, DB.admin, UUID("foo-123-567-foo"))
}
}
def addUser(name: String, email: Email, password: Password, role: Role = simpleUser): Unit = {
addUser(name, email, password, role, UUID(util.UUID.randomUUID().toString))
def addUser(name: String, email: Email, password: Password, omVersion: Version, lastAccess: Long, role: Role = simpleUser): Unit = {
addUser(name, email, password, omVersion, lastAccess, role, UUID(util.UUID.randomUUID().toString))
}
def addUser(name: String, email: Email, password: Password, role: Role, uuid: UUID): Unit = {
def addUser(name: String, email: Email, password: Password, omVersion: Version, lastAccess: Long, role: Role, uuid: UUID): Unit = {
if (!exists(email)) {
runTransaction(
userTable += (uuid, name, email, password, role)
userTable += (uuid, name, email, password, role, omVersion, lastAccess)
)
}
}
def upsert(user: User) = {
runTransaction(
userTable.insertOrUpdate(user.uuid, user.name, user.email, user.password, user.role)
userTable.insertOrUpdate(user.uuid, user.name, user.email, user.password, user.role, user.omVersion, user.lastAccess)
)
}
def setLastAccess(email: Email, lastAccess: Long) =
runTransaction {
getLastAccesQuery(email).update(lastAccess)
}
def delete(user: User) = {
runTransaction(
userTable.filter {
_.uuid === user.uuid
}.delete
)
}
......
......@@ -10,14 +10,14 @@ import scala.concurrent.ExecutionContext.Implicits.global
import shared._
object DBQueries {
type UserQuery = Query[Users, (UUID, String, Email, Password, Role), Seq]
type UserQuery = Query[Users, (UUID, String, Email, Password, Role, Version, Long), Seq]
def runQuery(query: UserQuery) =
Await.result(
db.run(
query.result
), Duration.Inf
).map { case (u, n, e, p, r) => User(n, e, p, r, u) }
).map { case (u, n, e, p, r, v, l) => User(n, e, p, v, l, r, u) }
// Query statements
def getQuery(email: Email) =
......@@ -25,4 +25,9 @@ object DBQueries {
u <- userTable if (u.email === email)
} yield (u)
def getLastAccesQuery(email: Email) =
for {
u <- userTable if (u.email === email)
} yield (u.lastAccess)
}
package org.openmoleconnect.server
object Utils {
object openmoleversion {
def stable = DB.Version("FIXME STABLE")
def developpement = DB.Version("FIXME DEV")
}
}
......@@ -7,4 +7,6 @@ trait AdminApi {
def users(): Seq[UserData]
def upserted(userData: UserData): Seq[UserData]
def delete(userData: UserData): Seq[UserData]
}
\ No newline at end of file
......@@ -14,7 +14,9 @@ object Data {
val off: Status = "Off"
val error: Status = "Error"
case class UserData(name: String, email: String, password: String, role: Role)
case class UserData(name: String, email: String, password: String, role: Role, omVersion: String, lastAccess: Long)
case class PersonalUserData(name: String, email: String, password: String, role: Role)
case class UserStatus(uuid: String, status: Status)
......
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