Skip to content

Release/0.9.5 #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 100 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
2607136
Implementation of /authenticate endpoint at Delphi Management end ref…
Ayybeeshafi Feb 16, 2019
8363724
Merge remote-tracking branch 'origin/develop' into feature/userAuth
janniclas Feb 18, 2019
5b0250a
reading username password from actual http request
janniclas Feb 18, 2019
84953eb
added auth service
janniclas Feb 18, 2019
d5cb0cf
ishwaryamamidi Feb 18, 2019
700c27d
Basic login form design
ishwaryamamidi Feb 18, 2019
201aa29
Update landing-page.component.ts
ishwaryamamidi Feb 18, 2019
1022d1c
Update landing-page.component.css
ishwaryamamidi Feb 18, 2019
ea12fb4
Merge remote-tracking branch 'origin/feature/userAuth' into feature/u…
ishwaryamamidi Feb 18, 2019
eaf3df8
Merge pull request #120 from delphi-hub/release/0.9.0
janniclas Feb 19, 2019
488f074
added basic auth service
janniclas Feb 19, 2019
37bdbac
Merge branch 'feature/userAuth' of github.com:delphi-hub/delphi-manag…
janniclas Feb 19, 2019
90043d8
fixed incorrect module usage of landing page component
janniclas Feb 19, 2019
becbabd
fixed auth service test setup. cleaned some unused imports from test …
janniclas Feb 19, 2019
1c39285
ishwaryamamidi Feb 20, 2019
16bb8fa
Validation of token refs #117
Ayybeeshafi Feb 20, 2019
a00b09a
added auth library to validate jwt tokens.
janniclas Feb 21, 2019
42fd5ba
basic is valid and get token functionality
janniclas Feb 21, 2019
78552d9
Merge branch 'develop' into feature/userAuth
janniclas Feb 21, 2019
bcf05ee
bumped version to 0.9.5-SNAPSHOT
janniclas Feb 21, 2019
6853445
removed import, which was added by mistake.
janniclas Feb 21, 2019
02935eb
Simplified boolean expressions refs #117
Ayybeeshafi Feb 21, 2019
c536425
Introduction of Writable JSON in Authenticate request
Ayybeeshafi Feb 21, 2019
7efb863
Custom labels can be added to the labels.
Naveenkumar27 Feb 21, 2019
9d794a2
Fix of broken code
Ayybeeshafi Feb 21, 2019
d70c069
Increased the canvas size
ishwaryamamidi Feb 21, 2019
8eb0824
using dependency injection to create the jwt helper service
janniclas Feb 21, 2019
b5d6329
using reactive forms
janniclas Feb 21, 2019
ead1d9a
added injector for http requests to append the user token if it exists
janniclas Feb 21, 2019
fb73fb4
Merge branch 'feature/userAuth' of github.com:delphi-hub/delphi-manag…
janniclas Feb 21, 2019
54e0601
using login provided in auth service instead of direct usage by api s…
janniclas Feb 21, 2019
3db52ac
fixed scala play auth request to instance registry
janniclas Feb 21, 2019
e5e1be8
removed control log of appending the auth token
janniclas Feb 21, 2019
0d4787a
Add Datasource
winniedo Feb 21, 2019
481ea48
added route auth guards to limit the access for unauthorized users to…
janniclas Feb 21, 2019
46427c4
described how to skip authorization
janniclas Feb 21, 2019
5fc0560
Merge pull request #122 from delphi-hub/issue/112
janniclas Feb 21, 2019
10fe6a0
Update dataSource
winniedo Feb 21, 2019
9f01580
Update table on info center
Feb 21, 2019
7d7682c
review code
winniedo Feb 21, 2019
9b9310c
Added test cases for label-dialog component and fixed build issue
Naveenkumar27 Feb 22, 2019
45f4780
removed unnecessary changes in karma.config.js
Naveenkumar27 Feb 22, 2019
0ed8fab
ishwaryamamidi Feb 23, 2019
9e5d6ff
Merge remote-tracking branch 'origin/feature/userAuth' into feature/u…
ishwaryamamidi Feb 23, 2019
a389224
ishwaryamamidi Feb 23, 2019
3413373
Code cleaning and formating
Ayybeeshafi Feb 25, 2019
61cddc9
ishwaryamamidi Feb 28, 2019
1b9ca34
Merge remote-tracking branch 'origin/feature/userAuth' into feature/u…
ishwaryamamidi Feb 28, 2019
7e6b225
Merge branch 'develop' into feature/addLabels
Naveenkumar27 Feb 28, 2019
3a4076f
Removed unnecessary logs and post request method
Naveenkumar27 Feb 28, 2019
70962ab
fix bugs
winniedo Mar 3, 2019
cdf43eb
Merge branch 'develop' into feature/informationCenter
winniedo Mar 3, 2019
4d386ec
User auth at each endpoint refs #117
Ayybeeshafi Mar 4, 2019
68eb4ad
fixed linting errors
janniclas Mar 5, 2019
d21214c
added hot reloading functionality for add label.
janniclas Mar 5, 2019
7592e4b
added empty initialization of matdatasource
janniclas Mar 5, 2019
e6b3c95
Merge pull request #124 from delphi-hub/feature/addLabels
janniclas Mar 5, 2019
1dbf4ca
Merge branch 'develop' into feature/informationCenter
winniedo Mar 7, 2019
8f523c0
Added feedback for failed delete operation
Naveenkumar27 Mar 7, 2019
04e730f
fix bugs test cases
winniedo Mar 7, 2019
e46ea26
Merge remote-tracking branch 'origin/feature/informationCenter' into …
winniedo Mar 7, 2019
17ca119
Added 'Enter Key press event' for adding a Label
Naveenkumar27 Mar 7, 2019
9f8eb86
created custom authAction
janniclas Mar 7, 2019
9d35bd9
fixed login page input links
janniclas Mar 7, 2019
d663348
added authorization to all endpoints
janniclas Mar 7, 2019
0b8f8a0
added user auth for system info controller
janniclas Mar 7, 2019
8194324
style fixes
janniclas Mar 7, 2019
2dd09d9
fixed imports
janniclas Mar 7, 2019
a6d8284
removed uncommented code
janniclas Mar 7, 2019
f31bb37
removed sampletoken
janniclas Mar 7, 2019
4d11a9c
removed username / password output on server
janniclas Mar 7, 2019
65dba2c
added refresh token todo and removed uncommented code
janniclas Mar 7, 2019
2904c3a
merged dev and updated dependencies
janniclas Mar 7, 2019
463ca59
Update table-all.component.ts
janniclas Mar 7, 2019
513d6e6
Update label-dialog.component.ts
janniclas Mar 7, 2019
6fe6019
style fixes
janniclas Mar 7, 2019
ff58100
Merge pull request #126 from delphi-hub/feature/deleteInstanceFeedback
janniclas Mar 7, 2019
70c9b79
Merge branch 'develop' into feature/userAuth
janniclas Mar 7, 2019
d833c44
errors fixed
winniedo Mar 7, 2019
a508f29
Merge branch 'develop' into feature/informationCenter
winniedo Mar 7, 2019
07af49d
/informationCenter: Auto stash before merge of "feature/informationCe…
winniedo Mar 7, 2019
30c660d
Code cleanup and commenting
Ayybeeshafi Mar 7, 2019
737f66b
improved usage of optional type
janniclas Mar 8, 2019
47faf79
added types to comparator function
janniclas Mar 8, 2019
c6446bc
code reusage for all events in info center
janniclas Mar 8, 2019
fa3b4e7
Update InstanceRegistryController.scala
janniclas Mar 8, 2019
3c7e5a9
fixed import style
janniclas Mar 8, 2019
11af349
fixed multiple socket notification events
janniclas Mar 8, 2019
8b5fe5f
fixed data format of info center to match the actually created element
janniclas Mar 8, 2019
9174864
Merge pull request #127 from delphi-hub/feature/userAuth
Ayybeeshafi Mar 8, 2019
7b61194
test cases and code Review
winniedo Mar 13, 2019
bd1c13d
Code review
winniedo Mar 13, 2019
922853b
updated dependencies
janniclas Mar 14, 2019
be812ac
merged develop
janniclas Mar 14, 2019
e425791
Merge pull request #125 from delphi-hub/feature/informationCenter
janniclas Mar 14, 2019
d0f6bca
providing userIsAdmin method
janniclas Mar 14, 2019
50b6dd7
style change
janniclas Mar 14, 2019
3016c4e
Merge pull request #133 from delphi-hub/feature/checkUserIsAdmin
ishwaryamamidi Mar 17, 2019
d48dcb1
bumped version number
janniclas Mar 17, 2019
cd8b8f8
Merge branch 'master' into release/0.9.5
janniclas Mar 17, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions app/authorization/AuthAction.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (C) 2018 The Delphi Team.
// See the LICENCE file distributed with this work for additional
// information regarding copyright ownership.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package authorization

import javax.inject.Inject
import pdi.jwt._
import play.api.http.HeaderNames
import play.api.mvc._
import authorization.AuthProvider
import play.api.Configuration

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}

// A custom request type to hold our JWT claims, we can pass these on to the
// handling action
//case class UserRequest[A](jwt: JwtClaim, token: String, request: Request[A]) extends WrappedRequest[A](request)

// Our custom action implementation
class AuthAction @Inject()(bodyParser: BodyParsers.Default)(implicit ec: ExecutionContext, config: Configuration)
extends ActionBuilder[Request, AnyContent] {

override def parser: BodyParser[AnyContent] = bodyParser
override protected def executionContext: ExecutionContext = ec

// A regex for parsing the Authorization header value
private val headerTokenRegex = """Bearer (.+?)""".r

// Called when a request is invoked. We should validate the bearer token here
// and allow the request to proceed if it is valid.
override def invokeBlock[A](request: Request[A], block: Request[A] => Future[Result]): Future[Result] =
extractBearerToken(request) map { token =>
if(AuthProvider.validateJwt(token)) {
block(request) // token was valid - proceed!
} else {
Future.successful(Results.Unauthorized("Invalid")) // token was invalid - return 401
}
} getOrElse Future.successful(Results.Unauthorized) // no token was sent - return 401

// Helper for extracting the token value
private def extractBearerToken[A](request: Request[A]): Option[String] =
request.headers.get(HeaderNames.AUTHORIZATION) collect {
case headerTokenRegex(token) => token
}
}
50 changes: 33 additions & 17 deletions app/authorization/AuthProvider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,47 @@
package authorization



import pdi.jwt.{Jwt, JwtAlgorithm, JwtClaim}
import play.api.Configuration

object AuthProvider {

var Token = "" // scalastyle:ignore

/** This method generates JWT token for registering Delphi-Management at the Instance-Registry
*
* @param validFor
object AuthProvider {

var Token = "" // scalastyle:ignore

/** This method generates JWT token for registering Delphi-Management at the Instance-Registry
*
* @param validFor
* @return
*/

def generateJwt(validFor: Long = 1)(implicit configuration: Configuration): String = {
val jwtSecretKey = configuration.get[String]("play.http.secret.JWTkey")
if (Token == "" || !Jwt.isValid(Token, jwtSecretKey, Seq(JwtAlgorithm.HS256))) {
val claim = JwtClaim()
.issuedNow
.expiresIn(validFor * 300)
.startsNow
. +("user_id", configuration.get[String]("play.http.instance"))
. +("user_type", "Admin")

Token = Jwt.encode(claim, jwtSecretKey, JwtAlgorithm.HS256)
}
Token
}

/**
* This method receives a token and validates if it is valid
* @param token
* @param configuration
* @return
*/

def generateJwt(validFor: Long = 1)(implicit configuration: Configuration): String = {
def validateJwt(token: String)(implicit configuration: Configuration): Boolean = {
val jwtSecretKey = configuration.get[String]("play.http.secret.JWTkey")
if (Token == "" || !Jwt.isValid(Token, jwtSecretKey, Seq(JwtAlgorithm.HS256))) {
val claim = JwtClaim()
.issuedNow
.expiresIn(validFor * 300)
.startsNow
. +("user_id", configuration.get[String]("play.http.instance"))
. +("user_type", "Admin")

Token = Jwt.encode(claim, jwtSecretKey, JwtAlgorithm.HS256)
}
Token
Jwt.isValid(token, jwtSecretKey, Seq(JwtAlgorithm.HS256)) // Decode the token using the secret key
}

}
2 changes: 2 additions & 0 deletions app/controllers/ApiRouter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,7 @@ class ApiRouter @Inject()(irController: InstanceRegistryController, sysControlle
case POST(p"/resumeInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/resume", instanceID)
case POST(p"/deleteInstance" ? q"instanceID=$instanceID") => irController.handleRequest(action="/delete", instanceID)
case POST(p"/reconnectInstance" ? q"from=$from"& q"to=$to") => irController.reconnect(from.toInt, to.toInt)
case POST(p"/authenticate") => irController.authentication()
case POST(p"/labelInstance" ? q"instanceID=$instanceID"& q"label=$label") => irController.labelInstance(instanceID, label)
}
}
98 changes: 82 additions & 16 deletions app/controllers/InstanceRegistryController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ import akka.actor.{ActorRef, ActorSystem}
import javax.inject.Inject
import play.api.{Configuration, Logger}
import play.api.libs.concurrent.CustomExecutionContext
import play.api.libs.ws.WSClient
import play.api.libs.ws.{WSAuthScheme, WSClient}
import akka.stream.Materializer
import play.api.libs.streams.ActorFlow
import actors.{ClientSocketActor, PublishSocketMessageActor}
import play.api.mvc._
import scala.concurrent.ExecutionContext
import authorization.AuthProvider
import play.api.libs.json.Json

import scala.concurrent.{Future, ExecutionContext}
import authorization.{AuthProvider, AuthAction}
import play.api.libs.json.{Json, JsValue}


trait MyExecutionContext extends ExecutionContext
Expand All @@ -55,7 +54,7 @@ class MyExecutionContextImpl @Inject()(implicit system: ActorSystem)

class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Materializer, myExecutionContext: MyExecutionContext,
val controllerComponents: ControllerComponents,
ws: WSClient, config: Configuration)
ws: WSClient, config: Configuration, authAction: AuthAction)
extends BaseController {


Expand All @@ -64,12 +63,13 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
val instanceRegistryUri = config.get[String]("app.instanceRegistryUri")
val instanceRegistryBasePath = config.get[String]("app.instanceRegistryBasePath")

/**This method maps list of instances with specific componentType.

/** This method maps list of instances with specific componentType.
*
* @param componentType
* @return
*/
def instances(componentType: String): Action[AnyContent] = Action.async {
def instances(componentType: String): Action[AnyContent] = authAction.async {
ws.url(instanceRegistryUri).addQueryStringParameters("ComponentType" -> componentType)
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
.get().map { response =>
Expand All @@ -87,13 +87,13 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
}
}

/**Called to fetch network graph of current registry. Contains a list of all instances and all links
/** Called to fetch network graph of current registry. Contains a list of all instances and all links
* currently registered.
*
* @return
*/

def getNetwork(): Action[AnyContent] = Action.async {
def getNetwork(): Action[AnyContent] = authAction.async {
ws.url(instanceRegistryUri + "/instances/network").withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
.get().map { response =>
// TODO: possible handling of parsing the data can be done here
Expand All @@ -114,7 +114,7 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
* @return
*/

def numberOfInstances(componentType: String): Action[AnyContent] = Action.async {
def numberOfInstances(componentType: String): Action[AnyContent] = authAction.async {
// TODO: handle what should happen if the instance registry is not reachable.
// TODO: create constants for the urls
ws.url(instanceRegistryUri + "/count").addQueryStringParameters("ComponentType" -> componentType)
Expand All @@ -137,7 +137,7 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
*/


def handleRequest(action: String, instanceID: String): Action[AnyContent] = Action.async { request =>
def handleRequest(action: String, instanceID: String): Action[AnyContent] = authAction.async { request =>
ws.url(instanceRegistryUri + "/instances/" + instanceID + action)
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
.post("")
Expand All @@ -146,7 +146,14 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
}(myExecutionContext)
}

def reconnect(from: Int, to: Int): Action[AnyContent] = Action.async { request =>
/**
* This method is called to assign a new instance to the instance with specified ID.
* @param from
* @param to
* @return
*/

def reconnect(from: Int, to: Int): Action[AnyContent] = authAction.async { request =>

ws.url(instanceRegistryUri + "/instances/" + from + "/assignInstance"
)
Expand All @@ -161,6 +168,7 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
}
}(myExecutionContext)
}

/**
* This function is for handling an POST request for adding an instance to the Scala web server
* (E.g. .../instances/deploy
Expand All @@ -169,12 +177,70 @@ class InstanceRegistryController @Inject()(implicit system: ActorSystem, mat: Ma
* @param name
*/

def postInstance(compType: String, name: String): Action[AnyContent] = Action.async
def postInstance(compType: String, name: String): Action[AnyContent] = authAction.async {
request =>
ws.url(instanceRegistryUri + "/instances/deploy")
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
.post(Json.obj("ComponentType" -> compType, "InstanceName" -> name))
.map { response =>
response.status match {
// scalastyle:off magic.number
case 202 =>
// scalastyle:on magic.number
Ok(response.body)
case x: Any =>
new Status(x)
}
}(myExecutionContext)
}

/**
* This function sends JWT token and Username:Password encoded into the headers to Instance Registry
* Instance registry returns a valid JWT token.
*
* @return
*/

def authentication(): Action[AnyContent] = Action.async {
request =>
//val json = request.body.asJson.get


val jsonBody: Option[JsValue] = request.body.asJson

jsonBody.map { json =>

val username = (json \ "username").as[String]
val password = (json \ "password").as[String]

ws.url(instanceRegistryUri + "/users" + "/authenticate")
.withAuth(username, password, WSAuthScheme.BASIC)
.withHttpHeaders(("Delphi-Authorization", s"${AuthProvider.generateJwt()}"))
.post("")
.map { response =>
if (response.status == 200) {
Ok(Json.obj("token" -> response.body, "refreshToken" -> ""))
} else {
new Status(response.status)
}
}
}.getOrElse{ Future(BadRequest("Invalid body"))}

}

/**
* This function is used to add a label to specific instance.
* @param instanceID ID of the instance on which label is to be added
* @param label
* @return
*/

def labelInstance(instanceID: String, label: String): Action[AnyContent] = authAction.async
{
request =>
ws.url(instanceRegistryUri + "/instances/deploy")
ws.url(instanceRegistryUri + "/instances/" + instanceID + "/label")
.withHttpHeaders(("Authorization", s"Bearer ${AuthProvider.generateJwt()}"))
.post(Json.obj("ComponentType" -> compType, "InstanceName" -> name))
.post(Json.obj("Label" -> label))
.map { response =>
response.status match {
// scalastyle:off magic.number
Expand Down
12 changes: 5 additions & 7 deletions app/controllers/SystemInfoController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, BaseController, ControllerComponents}
import play.core.PlayVersion
import authorization.AuthAction
import play.api.Configuration


class SystemInfoController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
class SystemInfoController @Inject()(val controllerComponents: ControllerComponents, config: Configuration, authAction: AuthAction) extends BaseController {
implicit val systemInfoWrites = Json.writes[SystemInfo]
implicit val systemInfoReads = Json.reads[SystemInfo]

def getInfo: Action[AnyContent] = Action {
def getInfo: Action[AnyContent] = authAction {

val info = SystemInfo(hostName = getHostName(), javaVersion = getJvmVersion(), platformName = getPlatformName(), scalaVersion = getScalaVersion())
val infoJson = Json.toJson(info)
Expand All @@ -44,13 +45,10 @@
}
}



private def getHostName(): String = {
private def getHostName(): String = {
InetAddress.getLocalHost().getHostName()
}


private def getPlatformName(): String = {
val os = "os.name";
val version = "os.version";
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name := "delphi-management"
organization := "de.upb"


version := "0.9.0"
version := "0.9.5"


scalaVersion := "2.12.4"
Expand Down
Loading