Skip to content

Commit fb5edde

Browse files
committed
Add user functionality added
1 parent 9c311d1 commit fb5edde

File tree

6 files changed

+135
-11
lines changed

6 files changed

+135
-11
lines changed

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/RequestHandler.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,24 @@ class RequestHandler(configuration: Configuration, authDao: AuthDAO, instanceDao
943943
}
944944
}
945945

946+
/**
947+
* Add user to user database
948+
*
949+
* @param user
950+
* @return
951+
*/
952+
def handleAddUser(user: DelphiUser): Try[Long] = {
953+
954+
val noIdUser = DelphiUser(id = None, userName = user.userName, secret = user.secret, userType = user.userType)
955+
956+
authDao.addUser(noIdUser) match {
957+
case Success(id) =>
958+
log.info(s"Successfully handled create user request")
959+
Success(id)
960+
case Failure(x) => Failure(x)
961+
}
962+
}
963+
946964

947965
def isInstanceIdPresent(id: Long): Boolean = {
948966
instanceDao.hasInstance(id)

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/connection/Server.scala

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import akka.stream.scaladsl.{Flow, Sink, Source}
1111
import de.upb.cs.swt.delphi.instanceregistry.authorization.AccessTokenEnums.UserType
1212
import de.upb.cs.swt.delphi.instanceregistry.authorization.{AccessToken, AuthProvider}
1313
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model.InstanceEnums.ComponentType
14-
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model.{EventJsonSupport, Instance, InstanceJsonSupport, InstanceLinkJsonSupport}
14+
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model._
1515
import de.upb.cs.swt.delphi.instanceregistry.requestLimiter.{IpLogActor, RequestLimitScheduler}
1616
import de.upb.cs.swt.delphi.instanceregistry.{AppLogging, Registry, RequestHandler}
1717
import spray.json.JsonParser.ParsingException
@@ -25,6 +25,7 @@ import scala.util.{Failure, Success, Try}
2525
*/
2626
class Server(handler: RequestHandler) extends HttpApp
2727
with InstanceJsonSupport
28+
with RequestJsonSupport
2829
with EventJsonSupport
2930
with InstanceLinkJsonSupport
3031
with AppLogging {
@@ -129,6 +130,13 @@ class Server(handler: RequestHandler) extends HttpApp
129130
}
130131
}
131132
} ~
133+
pathPrefix("users") {
134+
path("add") {
135+
entity(as[String]) {
136+
jsonString => addUser(jsonString)
137+
}
138+
}
139+
}~
132140
path("events") {
133141
streamEvents()
134142
} ~
@@ -1102,5 +1110,38 @@ class Server(handler: RequestHandler) extends HttpApp
11021110
}
11031111
}
11041112

1113+
def addUser(UserString: String): server.Route = Route.seal{
1114+
1115+
authenticateOAuth2[AccessToken]("Secure Site", handler.authProvider.authenticateOAuthRequire(_, userType = UserType.Admin)) { token =>
1116+
1117+
post {
1118+
log.debug(s"POST /users/add has been called, parameter is: $UserString")
1119+
1120+
try {
1121+
val paramInstance: DelphiUser = UserString.parseJson.convertTo[DelphiUser](AuthDelphiUserFormat)
1122+
handler.handleAddUser(paramInstance) match {
1123+
case Success(id) =>
1124+
complete {
1125+
id.toString
1126+
}
1127+
case Failure(ex) =>
1128+
log.error(ex, "Failed to handle registration of instance.")
1129+
complete(HttpResponse(StatusCodes.InternalServerError, entity = "An internal server error occurred."))
1130+
}
1131+
} catch {
1132+
case dx: DeserializationException =>
1133+
log.error(dx, "Deserialization exception")
1134+
complete(HttpResponse(StatusCodes.BadRequest, entity = s"Could not deserialize parameter instance with message ${dx.getMessage}."))
1135+
case px: ParsingException =>
1136+
log.error(px, "Failed to parse JSON while registering")
1137+
complete(HttpResponse(StatusCodes.BadRequest, entity = s"Failed to parse JSON entity with message ${px.getMessage}"))
1138+
case x: Exception =>
1139+
log.error(x, "Uncaught exception while deserializing.")
1140+
complete(HttpResponse(StatusCodes.InternalServerError, entity = "An internal server error occurred."))
1141+
}
1142+
}
1143+
}
1144+
}
1145+
11051146
}
11061147

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/daos/AuthDAO.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package de.upb.cs.swt.delphi.instanceregistry.daos
22

3-
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model.{DelphiUser}
3+
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model.DelphiUser
4+
5+
import scala.util.Try
46

57
trait AuthDAO {
68

9+
/**
10+
* Add user
11+
* @return
12+
*/
13+
def addUser(delphiUser : DelphiUser) : Try[Long]
14+
715
/**
816
* Initializes the DAO
917
*/

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/daos/DatabaseAuthDAO.scala

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package de.upb.cs.swt.delphi.instanceregistry.daos
22

33

4+
import java.nio.charset.StandardCharsets
5+
46
import akka.actor.ActorSystem
57
import akka.stream.ActorMaterializer
8+
9+
import scala.concurrent.Future
10+
import scala.util.{Failure, Success}
611
import de.upb.cs.swt.delphi.instanceregistry.{AppLogging, Configuration, Registry}
712
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model._
813
import slick.lifted.TableQuery
@@ -12,6 +17,8 @@ import slick.jdbc.MySQLProfile.api._
1217
import slick.jdbc.meta.MTable
1318

1419
import scala.concurrent.duration.Duration
20+
import scala.util.Try
21+
import java.security.MessageDigest
1522

1623
class DatabaseAuthDAO (configuration : Configuration) extends AuthDAO with AppLogging{
1724

@@ -26,12 +33,30 @@ class DatabaseAuthDAO (configuration : Configuration) extends AuthDAO with AppLo
2633
{
2734
if(hasUserWithUsername(userName)) {
2835
val result = Await.result(dbAuth.run(users.filter(_.userName === userName).result.headOption), Duration.Inf)
29-
Some(dataToObjectAuthenticate(result.get._2, result.get._3, result.get._4))
36+
Some(dataToObjectAuthenticate(result.get._1, result.get._2, result.get._3, result.get._4))
3037
} else {
3138
None
3239
}
3340
}
3441

42+
override def addUser(delphiUser : DelphiUser) : Try[Long] = {
43+
if(hasUserWithUsername(delphiUser.userName)){
44+
Failure(new RuntimeException(s"username ${delphiUser.userName} is already exist."))
45+
} else {
46+
val id = 0L //Will be set by DB
47+
val userName = delphiUser.userName
48+
val secret = delphiUser.secret
49+
val userType = delphiUser.userType
50+
51+
val addFuture: Future[Long] = dbAuth.run((users returning users.map(_.id)) += (id, userName, hashString(secret), userType))
52+
val userId = Await.result(addFuture, Duration.Inf)
53+
54+
log.info(s"Added user ${delphiUser.userName} with id $userId to database.")
55+
Success(userId)
56+
}
57+
58+
}
59+
3560
override def hasUserWithUsername(username: String) : Boolean = {
3661
Await.result(dbAuth.run(users.filter(_.userName === username).exists.result), Duration.Inf)
3762
}
@@ -66,8 +91,8 @@ class DatabaseAuthDAO (configuration : Configuration) extends AuthDAO with AppLo
6691
log.info("Shutdown complete.")
6792
}
6893

69-
private def dataToObjectAuthenticate(userName: String, secret: String, userType: String): DelphiUser = {
70-
DelphiUser.apply(userName, secret, userType)
94+
private def dataToObjectAuthenticate(id:Long, userName: String, secret: String, userType: String): DelphiUser = {
95+
DelphiUser.apply(Option(id), userName, secret, userType)
7196
}
7297

7398
private def dbTest(): Boolean = {
@@ -82,4 +107,8 @@ class DatabaseAuthDAO (configuration : Configuration) extends AuthDAO with AppLo
82107
val action = users.delete
83108
dbAuth.run(action)
84109
}
110+
111+
private def hashString(secret: String): String = {
112+
MessageDigest.getInstance("SHA-256").digest(secret.getBytes(StandardCharsets.UTF_8)).map("%02x".format(_)).mkString("")
113+
}
85114
}

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/daos/DynamicAuthDAO.scala

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package de.upb.cs.swt.delphi.instanceregistry.daos
22

3-
import java.io.File
3+
import java.nio.charset.StandardCharsets
4+
import java.security.MessageDigest
45

56
import akka.actor.ActorSystem
67
import akka.stream.ActorMaterializer
78
import de.upb.cs.swt.delphi.instanceregistry.io.swagger.client.model.DelphiUser
89
import de.upb.cs.swt.delphi.instanceregistry.{AppLogging, Configuration, Registry}
10+
911
import scala.collection.mutable
1012
import scala.concurrent.ExecutionContext
13+
import scala.util.{Failure, Success, Try}
1114

1215
class DynamicAuthDAO (configuration : Configuration) extends AuthDAO with AppLogging{
1316
implicit val system : ActorSystem = Registry.system
@@ -21,13 +24,27 @@ class DynamicAuthDAO (configuration : Configuration) extends AuthDAO with AppLog
2124
if(hasUserWithUsername(userName)) {
2225
val query = users filter {i => i.userName == userName}
2326
val user = query.iterator.next()
24-
Some(dataToObjectAuthenticate(user.userName, user.secret, user.userType))
27+
Some(dataToObjectAuthenticate(user.id.get, user.userName, user.secret, user.userType))
2528
} else {
2629
None
2730
}
2831

2932
}
3033

34+
override def addUser(delphiUser : DelphiUser) : Try[Long] = {
35+
if(hasUserWithUsername(delphiUser.userName)){
36+
Failure(new RuntimeException(s"username ${delphiUser.userName} is already exist."))
37+
} else{
38+
val id = nextId()
39+
val newUser = DelphiUser(Some(id), delphiUser.userName, hashString(delphiUser.secret), delphiUser.userType)
40+
users.add(newUser)
41+
42+
log.info(s"Added user ${newUser.userName} with id ${newUser.id.get} to database.")
43+
Success(id)
44+
}
45+
46+
}
47+
3148
override def hasUserWithUsername(username: String) : Boolean = {
3249
val query = users filter {i => i.userName == username}
3350
query.nonEmpty
@@ -46,13 +63,24 @@ class DynamicAuthDAO (configuration : Configuration) extends AuthDAO with AppLog
4663
log.info("Shutdown complete dynamic Auth DAO.")
4764
}
4865

49-
private def dataToObjectAuthenticate(userName: String, secret: String, userType: String): DelphiUser = {
50-
DelphiUser.apply(userName, secret, userType)
66+
private def dataToObjectAuthenticate(id:Long, userName: String, secret: String, userType: String): DelphiUser = {
67+
DelphiUser.apply(Option(id), userName, secret, userType)
5168
}
5269

5370

5471
private[daos] def clearData() : Unit = {
5572
users.clear()
5673
}
5774

75+
private def nextId(): Long = {
76+
if(users.isEmpty){
77+
0L
78+
} else {
79+
(users.map(i => i.id.getOrElse(0L)) max) + 1L
80+
}
81+
}
82+
83+
private def hashString(secret: String): String = {
84+
MessageDigest.getInstance("SHA-256").digest(secret.getBytes(StandardCharsets.UTF_8)).map("%02x".format(_)).mkString("")
85+
}
5886
}

src/main/scala/de/upb/cs/swt/delphi/instanceregistry/io/swagger/client/model/RequestJsonSupport.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ trait RequestJsonSupport extends SprayJsonSupport with DefaultJsonProtocol{
2020
}
2121
}
2222

23-
implicit val AuthDelphiUserFormat: JsonFormat[DelphiUser] = jsonFormat3(DelphiUser)
23+
implicit val AuthDelphiUserFormat: JsonFormat[DelphiUser] = jsonFormat4(DelphiUser)
2424
}
2525

26-
final case class DelphiUser(userName: String, secret: String, userType: String)
26+
final case class DelphiUser(id: Option[Long], userName: String, secret: String, userType: String)
2727

2828
object delphiUserEnums {
2929

0 commit comments

Comments
 (0)