123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /*
- * Copyright (C) 2020 Prasoon Joshi
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- package repository
- import repository.NiosxGraph._
- import models.{
- NiosxUser, AuthPayload
- }
- import utils.{FileUtils, SecurityUtils}
- import graphql.SchemaInputObjects.UserInput
- import play.api.libs.ws.WSClient
- import play.api.Configuration
- import scala.util.Try
- import scala.collection.mutable
- sealed trait UserRole
- object UserRole {
- val PartnerPermissions =
- "VIEW_USER" :: "EDIT_ENTITY" :: "VIEW_ENTITY" :: "EDIT_ANNO" :: "VIEW_ANNO" :: Nil
- val PatronPermissions =
- "VIEW_USER" :: "EDIT_ANNO" :: "VIEW_ANNO" :: Nil
- val AdminPermissions = PartnerPermissions ++ PatronPermissions ++
- ("EDIT_USER" :: "VIEW_USER" :: "SUPER_USER" :: Nil)
- def getUserPermissions(r: String): List[String] = getRole(r) match {
- case NiosxAdminRole => AdminPermissions
- case NiosxPartnerRole => PartnerPermissions
- case NiosxPatronRole => PatronPermissions
- }
- def getRole(r: String): UserRole = r match {
- case "admin" => NiosxAdminRole
- case "partner" => NiosxPartnerRole
- case "patron" => NiosxPatronRole
- }
- def roleToString(r: UserRole): String = r match {
- case NiosxAdminRole => "admin"
- case NiosxPartnerRole => "partner"
- case NiosxPatronRole => "patron"
- }
- }
- case object NiosxAdminRole extends UserRole
- case object NiosxPartnerRole extends UserRole
- case object NiosxPatronRole extends UserRole
- class SimpleUserRepository(ws: WSClient,
- gs: GremlinServer,
- conf: Configuration) extends UserRepository {
- //TODO: This needs a better approach to be able to support large
- //number of concurrent users.
- var UserTokenMap: mutable.Map[String, String] = mutable.Map()
- //TODO: Handle bulk upload better!
- val BULK_UPLOAD_USER: NiosxUser =
- new NiosxUser(graphId = "NA",
- username = "bulk_upload_user",
- passHash = SecurityUtils.hashPass(
- conf.get[String]("default.bulk.upload.key")),
- permissions = List("BULK_UPLOAD"),
- role = NiosxAdminRole)
- /**
- * A note on "super_duper_user":
- * In a "perfect" world, recommendation engines should be illegal.
- * People using the platform should be able to recommend stuff to
- * other people, the platform's task is to create these human connections
- * possible, not to create a trap!
- * A people graph is a powerful tool. It can be used effectively to
- * supress human connections or to mitigate falsehoods from spreading.
- * The design of the platform decides how people interact. The
- * "super_duper_user" is a step towards building a people graph which
- * enables people driven information sharing. Penalty for bad behaviour
- * would cascade down to all people/actors added to the system by the bad actor
- * and include the actor that introduced this bad actor into the system.
- */
- val SuperDuperUser: String = "superduperuser"
-
- //TODO: Move this to some initialize component/block.
- val suDuUsPass = conf.get[String]("default.admin.password")
- println(suDuUsPass)
- val suDuUser: Option[NiosxUser] =
- gs
- .Save[NiosxUser]
- .save(
- NiosxUser(graphId = SuperDuperUser,
- username = SuperDuperUser,
- passHash = SecurityUtils.hashPass(suDuUsPass),
- role = NiosxAdminRole,
- permissions = UserRole.getUserPermissions("admin")),
- edge = Darkness) match {
- case f: gs.SaveFailure => None
- case s: gs.SaveSuccess => gs.VertToCC[NiosxUser].convert(s.v)
- }
- def addUser(u: UserInput): String = {
- val user: NiosxUser = NiosxUser(
- graphId = FileUtils.getNewGraphId,
- username = u.username,
- passHash = SecurityUtils.hashPass(u.password),
- role = UserRole.getRole(u.role),
- permissions = UserRole.getUserPermissions(u.role))
-
- gs
- .findUserByUsername(u.username)
- .fold(
- gs
- .Save[NiosxUser]
- .save(user, Darkness) match {//Some(SuperDuperUser))
- case f: gs.SaveFailure => "Could not create user"
- case s: gs.SaveSuccess => s"User ${u.username} created."
- })(_ => s"User ${u.username} already exists!")
-
- }
-
- def editUser(u: UserInput): Option[NiosxUser] = ???
- // val user: NiosxUser = NiosxUser(
- // gremlinServer.Save[NiosxUser].save(user, None)
- /*
- * Gives back a token wrapped inside an `AuthPayload`
- * that identifies a user session.
- *
- */
- def authenticate(username: String,
- password: String): Option[AuthPayload] = {
- val user: Option[NiosxUser] = username match {
- case "bulk_upload_user" => Some(BULK_UPLOAD_USER)
- case _ => gs.findUserByUsername(username)
- }
- user.flatMap({ u: NiosxUser =>
- SecurityUtils.checkPass(password, u.passHash) match {
- case false => None
- case true => {
- val token: String = SecurityUtils.genUserToken
- UserTokenMap += (token -> u.username)
- //println("Token saved in map: " + token + ":" + UserTokenMap.get(token))
- Some(AuthPayload(token, u))
- }
- }
- })
- }
- //TODO: Redundant. Remove.
- def findUserByUsername(username: String): Option[NiosxUser] =
- gs.findUserByUsername(username)
-
- /**
- * Gives a user object with permissions.
- */
- def authorise(token: String): Option[NiosxUser] = {
- val user: Option[String] = UserTokenMap.get(token)
- user match {
- case Some("bulk_upload_user") => Some(BULK_UPLOAD_USER)
- case Some(u) => gs.findUserByUsername(u)
- case None => None
- }
- }
- }
|