mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 14:46:49 +00:00
Merge remote-tracking branch 'upstream/develop' into develop
This commit is contained in:
commit
345deb4ed2
@ -56,7 +56,7 @@ object ObpActorConfig {
|
||||
"code.model.dataAccess.ViewImpl" = kryo,
|
||||
"com.openbankproject.commons.model.User" = kryo,
|
||||
"com.openbankproject.commons.model.ViewId" = kryo,
|
||||
"com.openbankproject.commons.model.ViewIdBankIdAccountId" = kryo,
|
||||
"com.openbankproject.commons.model.BankIdAccountIdViewId" = kryo,
|
||||
"com.openbankproject.commons.model.Permission" = kryo,
|
||||
"scala.Unit" = kryo,
|
||||
"scala.Boolean" = kryo,
|
||||
|
||||
@ -4069,24 +4069,39 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
case _ => false
|
||||
}
|
||||
|
||||
def canGrantAccessToView(bankId: BankId, accountId: AccountId, viewIdTobeGranted : ViewId, user: User, callContext: Option[CallContext]): Boolean = {
|
||||
def canGrantAccessToView(bankId: BankId, accountId: AccountId, targetViewId : ViewId, user: User, callContext: Option[CallContext]): Boolean = {
|
||||
//all the permission this user have for the bankAccount
|
||||
val permission: Box[Permission] = Views.views.vend.permission(BankIdAccountId(bankId, accountId), user)
|
||||
|
||||
//1. if viewIdTobeGranted is systemView. just compare all the permissions
|
||||
if(checkSystemViewIdOrName(viewIdTobeGranted.value)){
|
||||
//1. if targetViewId is systemView. just compare all the permissions
|
||||
if(checkSystemViewIdOrName(targetViewId.value)){
|
||||
val allCanGrantAccessToViewsPermissions: List[String] = permission
|
||||
.map(_.views.map(_.canGrantAccessToViews.getOrElse(Nil)).flatten).getOrElse(Nil).distinct
|
||||
|
||||
allCanGrantAccessToViewsPermissions.contains(viewIdTobeGranted.value)
|
||||
allCanGrantAccessToViewsPermissions.contains(targetViewId.value)
|
||||
} else{
|
||||
//2. if viewIdTobeGranted is customView, we only need to check the `canGrantAccessToCustomViews`.
|
||||
//2. if targetViewId is customView, we only need to check the `canGrantAccessToCustomViews`.
|
||||
val allCanGrantAccessToCustomViewsPermissions: List[Boolean] = permission.map(_.views.map(_.canGrantAccessToCustomViews)).getOrElse(Nil)
|
||||
|
||||
allCanGrantAccessToCustomViewsPermissions.contains(true)
|
||||
}
|
||||
}
|
||||
|
||||
def canGrantAccessToView(bankIdAccountIdViewId: BankIdAccountIdViewId, targetViewId : ViewId, user: User, callContext: Option[CallContext]): Boolean = {
|
||||
|
||||
//1st: get the view
|
||||
val view: Box[View] = Views.views.vend.getViewByBankIdAccountIdViewIdUserPrimaryKey(bankIdAccountIdViewId, user.userPrimaryKey)
|
||||
|
||||
//2rd: f targetViewId is systemView. we need to check `view.canGrantAccessToViews` field.
|
||||
if(checkSystemViewIdOrName(targetViewId.value)){
|
||||
val canGrantAccessToView: Box[List[String]] = view.map(_.canGrantAccessToViews.getOrElse(Nil))
|
||||
canGrantAccessToView.getOrElse(Nil).contains(targetViewId.value)
|
||||
} else{
|
||||
//3rd. if targetViewId is customView, we need to check `view.canGrantAccessToCustomViews` field.
|
||||
view.map(_.canGrantAccessToCustomViews).getOrElse(false)
|
||||
}
|
||||
}
|
||||
|
||||
def canGrantAccessToMultipleViews(bankId: BankId, accountId: AccountId, viewIdsTobeGranted : List[ViewId], user: User, callContext: Option[CallContext]): Boolean = {
|
||||
//all the permission this user have for the bankAccount
|
||||
val permissionBox = Views.views.vend.permission(BankIdAccountId(bankId, accountId), user)
|
||||
|
||||
@ -252,20 +252,20 @@ object Consent {
|
||||
for {
|
||||
view <- consent.views
|
||||
} yield {
|
||||
val viewIdBankIdAccountId = ViewIdBankIdAccountId(ViewId(view.view_id), BankId(view.bank_id), AccountId(view.account_id))
|
||||
Views.views.vend.revokeAccess(viewIdBankIdAccountId, user)
|
||||
val bankIdAccountIdViewId = BankIdAccountIdViewId(BankId(view.bank_id), AccountId(view.account_id),ViewId(view.view_id))
|
||||
Views.views.vend.revokeAccess(bankIdAccountIdViewId, user)
|
||||
}
|
||||
val result =
|
||||
for {
|
||||
view <- consent.views
|
||||
} yield {
|
||||
val viewIdBankIdAccountId = ViewIdBankIdAccountId(ViewId(view.view_id), BankId(view.bank_id), AccountId(view.account_id))
|
||||
val bankIdAccountIdViewId = BankIdAccountIdViewId(BankId(view.bank_id), AccountId(view.account_id),ViewId(view.view_id))
|
||||
Views.views.vend.systemView(ViewId(view.view_id)) match {
|
||||
case Full(systemView) =>
|
||||
Views.views.vend.grantAccessToSystemView(BankId(view.bank_id), AccountId(view.account_id), systemView, user)
|
||||
case _ =>
|
||||
// It's not system view
|
||||
Views.views.vend.grantAccessToCustomView(viewIdBankIdAccountId, user)
|
||||
Views.views.vend.grantAccessToCustomView(bankIdAccountIdViewId, user)
|
||||
}
|
||||
"Added"
|
||||
}
|
||||
|
||||
@ -191,10 +191,13 @@ object ErrorMessages {
|
||||
val GatewayLoginNoJwtForResponse = "OBP-20046: There is no useful value for JWT."
|
||||
|
||||
val UserLacksPermissionCanGrantAccessToViewForTargetAccount =
|
||||
s"OBP-20047: The current user does not have access to a view which lists the target account in ${ViewDefinition.canGrantAccessToViews_.dbColumnName} permissions"
|
||||
val UserLacksPermissionCanRevokeAccessToViewForTargetAccount =
|
||||
s"OBP-20048: The current user does not have access to a view which lists the target account in ${ViewDefinition.canRevokeAccessToViews_.dbColumnName} permissions"
|
||||
|
||||
s"OBP-20047: If target viewId is system view, the current view.can_grant_access_to_views does not contains it. Or" +
|
||||
s"if target viewId is custom view, the current view.can_grant_access_to_custom_views is false."
|
||||
|
||||
val UserLacksPermissionCanRevokeAccessToViewForTargetAccount =
|
||||
s"OBP-20047: If target viewId is system view, the current view.can_revoke_access_to_views does not contains it. Or" +
|
||||
s"if target viewId is custom view, the current view.can_revoke_access_to_custom_views is false."
|
||||
|
||||
val UserNotSuperAdmin = "OBP-20050: Current User is not a Super Admin!"
|
||||
|
||||
val ElasticSearchIndexNotFound = "OBP-20051: Elasticsearch index or indices not found."
|
||||
|
||||
@ -464,38 +464,38 @@ object NewStyle extends MdcLoggable{
|
||||
} map { fullBoxOrException(_)
|
||||
} map { unboxFull(_) }
|
||||
|
||||
def grantAccessToView(account: BankAccount, u: User, viewIdBankIdAccountId : ViewIdBankIdAccountId, provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.grantAccessToView(u, viewIdBankIdAccountId, provider, providerId, callContext: Option[CallContext])
|
||||
def grantAccessToView(account: BankAccount, u: User, bankIdAccountIdViewId : BankIdAccountIdViewId, provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.grantAccessToView(u, bankIdAccountIdViewId, provider, providerId, callContext: Option[CallContext])
|
||||
} map {
|
||||
x => (unboxFullOrFail(
|
||||
x,
|
||||
callContext,
|
||||
UserLacksPermissionCanGrantAccessToViewForTargetAccount + s"Current ViewId(${viewIdBankIdAccountId.viewId.value}) and current UserId(${u.userId})",
|
||||
UserLacksPermissionCanGrantAccessToViewForTargetAccount + s"Current ViewId(${bankIdAccountIdViewId.viewId.value}) and current UserId(${u.userId})",
|
||||
403),
|
||||
callContext
|
||||
)
|
||||
}
|
||||
|
||||
def grantAccessToMultipleViews(account: BankAccount, u: User, viewIdBankIdAccountIds : List[ViewIdBankIdAccountId], provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.grantAccessToMultipleViews(u, viewIdBankIdAccountIds, provider, providerId, callContext: Option[CallContext])
|
||||
def grantAccessToMultipleViews(account: BankAccount, u: User, bankIdAccountIdViewIds : List[BankIdAccountIdViewId], provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.grantAccessToMultipleViews(u, bankIdAccountIdViewIds, provider, providerId, callContext: Option[CallContext])
|
||||
} map {
|
||||
x =>
|
||||
(unboxFullOrFail(
|
||||
x,
|
||||
callContext,
|
||||
UserLacksPermissionCanGrantAccessToViewForTargetAccount + s"Current ViewIds(${viewIdBankIdAccountIds}) and current UserId(${u.userId})",
|
||||
UserLacksPermissionCanGrantAccessToViewForTargetAccount + s"Current ViewIds(${bankIdAccountIdViewIds}) and current UserId(${u.userId})",
|
||||
403),
|
||||
callContext
|
||||
)
|
||||
}
|
||||
def revokeAccessToView(account: BankAccount, u: User, viewIdBankIdAccountId : ViewIdBankIdAccountId, provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.revokeAccessToView(u, viewIdBankIdAccountId, provider, providerId, callContext: Option[CallContext])
|
||||
def revokeAccessToView(account: BankAccount, u: User, bankIdAccountIdViewId : BankIdAccountIdViewId, provider : String, providerId: String, callContext: Option[CallContext]) = Future {
|
||||
account.revokeAccessToView(u, bankIdAccountIdViewId, provider, providerId, callContext: Option[CallContext])
|
||||
} map {
|
||||
x =>
|
||||
(unboxFullOrFail(
|
||||
x,
|
||||
callContext,
|
||||
UserLacksPermissionCanRevokeAccessToViewForTargetAccount + s"Current ViewId(${viewIdBankIdAccountId.viewId.value}) and current UserId(${u.userId})",
|
||||
UserLacksPermissionCanRevokeAccessToViewForTargetAccount + s"Current ViewId(${bankIdAccountIdViewId.viewId.value}) and current UserId(${u.userId})",
|
||||
403),
|
||||
callContext
|
||||
)
|
||||
@ -611,7 +611,7 @@ object NewStyle extends MdcLoggable{
|
||||
def grantAccessToCustomView(view : View, user: User, callContext: Option[CallContext]) : Future[View] = {
|
||||
view.isSystem match {
|
||||
case false =>
|
||||
Future(Views.views.vend.grantAccessToCustomView(ViewIdBankIdAccountId(view.viewId, view.bankId, view.accountId), user)) map {
|
||||
Future(Views.views.vend.grantAccessToCustomView(BankIdAccountIdViewId(view.bankId, view.accountId, view.viewId), user)) map {
|
||||
unboxFullOrFail(_, callContext, s"$CannotGrantAccountAccess Current ViewId is ${view.viewId.value}")
|
||||
}
|
||||
case true =>
|
||||
@ -623,7 +623,7 @@ object NewStyle extends MdcLoggable{
|
||||
def revokeAccessToCustomView(view : View, user: User, callContext: Option[CallContext]) : Future[Boolean] = {
|
||||
view.isSystem match {
|
||||
case false =>
|
||||
Future(Views.views.vend.revokeAccess(ViewIdBankIdAccountId(view.viewId, view.bankId, view.accountId), user)) map {
|
||||
Future(Views.views.vend.revokeAccess(BankIdAccountIdViewId(view.bankId, view.accountId, view.viewId), user)) map {
|
||||
unboxFullOrFail(_, callContext, s"$CannotRevokeAccountAccess Current ViewId is ${view.viewId.value}")
|
||||
}
|
||||
case true =>
|
||||
|
||||
@ -286,7 +286,7 @@
|
||||
// account <- BankAccount(bankId, accountId)
|
||||
// u <- user ?~ "user not found"
|
||||
// viewIds <- tryo{json.extract[ViewIdsJson]} ?~ "wrong format JSON"
|
||||
// addedViews <- account addPermissions(u, viewIds.views.map(viewIdString => ViewIdBankIdAccountId(ViewId(viewIdString), bankId, accountId)), authProvider, userId)
|
||||
// addedViews <- account addPermissions(u, viewIds.views.map(viewIdString => BankIdAccountIdViewId(bankId, accountId,ViewId(viewIdString))), authProvider, userId)
|
||||
// } yield {
|
||||
// val viewJson = JSONFactory.createViewsJSON(addedViews)
|
||||
// successJsonResponse(Extraction.decompose(viewJson), 201)
|
||||
@ -301,7 +301,7 @@
|
||||
// for {
|
||||
// account <- BankAccount(bankId, accountId)
|
||||
// u <- user ?~ "user not found"
|
||||
// addedView <- account addPermission(u, ViewIdBankIdAccountId(viewId, bankId, accountId), authProvider, userId)
|
||||
// addedView <- account addPermission(u, BankIdAccountIdViewId(bankId, accountId, viewId), authProvider, userId)
|
||||
// } yield {
|
||||
// val viewJson = JSONFactory.createViewJSON(addedView)
|
||||
// successJsonResponse(Extraction.decompose(viewJson), 201)
|
||||
@ -316,7 +316,7 @@
|
||||
// for {
|
||||
// account <- BankAccount(bankId, accountId)
|
||||
// u <- user ?~ "user not found"
|
||||
// isRevoked <- account revokePermission(u, ViewIdBankIdAccountId(viewId, bankId, accountId), authProvider, userId)
|
||||
// isRevoked <- account revokePermission(u, BankIdAccountIdViewId(bankId, accountId, viewId), authProvider, userId)
|
||||
// if(isRevoked)
|
||||
// } yield noContentJsonResponse
|
||||
// }
|
||||
|
||||
@ -848,7 +848,13 @@ trait APIMethods121 {
|
||||
(account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext)
|
||||
failMsg = "wrong format JSON"
|
||||
viewIds <- NewStyle.function.tryons(failMsg, 400, callContext) { json.extract[ViewIdsJson] }
|
||||
(addedViews, callContext) <- NewStyle.function.grantAccessToMultipleViews(account, u, viewIds.views.map(viewIdString => ViewIdBankIdAccountId(ViewId(viewIdString), bankId, accountId)), provider, providerId,callContext)
|
||||
(addedViews, callContext) <- NewStyle.function.grantAccessToMultipleViews(
|
||||
account, u,
|
||||
viewIds.views.map(viewIdString => BankIdAccountIdViewId(bankId, accountId,ViewId(viewIdString))),
|
||||
provider,
|
||||
providerId,
|
||||
callContext
|
||||
)
|
||||
} yield {
|
||||
(JSONFactory.createViewsJSON(addedViews), HttpCode.`201`(callContext))
|
||||
}
|
||||
@ -889,7 +895,7 @@ trait APIMethods121 {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
(_, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
(account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext)
|
||||
(addedView, callContext) <- NewStyle.function.grantAccessToView(account, u, ViewIdBankIdAccountId(viewId, bankId, accountId), provider, providerId, callContext)
|
||||
(addedView, callContext) <- NewStyle.function.grantAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext)
|
||||
} yield {
|
||||
val viewJson = JSONFactory.createViewJSON(addedView)
|
||||
(viewJson, HttpCode.`201`(callContext))
|
||||
@ -949,7 +955,7 @@ trait APIMethods121 {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
(_, callContext) <- NewStyle.function.getBank(bankId, callContext)
|
||||
(account, callContext) <- NewStyle.function.getBankAccount(bankId, accountId, callContext)
|
||||
_ <- NewStyle.function.revokeAccessToView(account, u, ViewIdBankIdAccountId(viewId, bankId, accountId), provider, providerId, callContext)
|
||||
_ <- NewStyle.function.revokeAccessToView(account, u, BankIdAccountIdViewId(bankId, accountId, viewId), provider, providerId, callContext)
|
||||
} yield {
|
||||
(Full(""), HttpCode.`204`(callContext))
|
||||
}
|
||||
|
||||
@ -4576,7 +4576,7 @@ trait APIMethods400 extends MdcLoggable {
|
||||
_ <- Future(Views.views.vend.revokeAccountAccessByUser(bankId, accountId, u, callContext)) map {
|
||||
unboxFullOrFail(_, callContext, s"Cannot revoke")
|
||||
}
|
||||
grantViews = for (viewId <- postJson.views) yield ViewIdBankIdAccountId(ViewId(viewId), bankId, accountId)
|
||||
grantViews = for (viewId <- postJson.views) yield BankIdAccountIdViewId(bankId, accountId, ViewId(viewId))
|
||||
_ <- Future(Views.views.vend.grantAccessToMultipleViews(grantViews, u, callContext)) map {
|
||||
unboxFullOrFail(_, callContext, s"Cannot grant the views: ${postJson.views.mkString(",")}")
|
||||
}
|
||||
@ -12678,25 +12678,12 @@ trait APIMethods400 extends MdcLoggable {
|
||||
Future.sequence(postJsonBody.roles.map(checkRoleName(callContext,_)))
|
||||
}
|
||||
|
||||
private def grantAccountAccessToUser(bankId: BankId, accountId: AccountId, user: User, view: View, callContext: Option[CallContext]) = {
|
||||
view.isSystem match {
|
||||
case true => NewStyle.function.grantAccessToSystemView(bankId, accountId, view, user, callContext)
|
||||
case false => NewStyle.function.grantAccessToCustomView(view, user, callContext)
|
||||
}
|
||||
}
|
||||
private def grantMultpleAccountAccessToUser(bankId: BankId, accountId: AccountId, user: User, views: List[View], callContext: Option[CallContext]) = {
|
||||
Future.sequence(views.map(view =>
|
||||
grantAccountAccessToUser(bankId: BankId, accountId: AccountId, user: User, view, callContext: Option[CallContext])
|
||||
))
|
||||
}
|
||||
|
||||
private def getView(bankId: BankId, accountId: AccountId, postView: PostViewJsonV400, callContext: Option[CallContext]) = {
|
||||
postView.is_system match {
|
||||
case true => NewStyle.function.systemView(ViewId(postView.view_id), callContext)
|
||||
case false => NewStyle.function.customView(ViewId(postView.view_id), BankIdAccountId(bankId, accountId), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
private def getViews(bankId: BankId, accountId: AccountId, postJson: PostCreateUserAccountAccessJsonV400, callContext: Option[CallContext]) = {
|
||||
Future.sequence(postJson.views.map(view => getView(bankId: BankId, accountId: AccountId, view: PostViewJsonV400, callContext: Option[CallContext])))
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ import java.util.Date
|
||||
|
||||
import code.api.Constant
|
||||
import code.api.attributedefinition.AttributeDefinition
|
||||
import code.api.util.APIUtil
|
||||
import code.api.util.{APIUtil, CallContext, NewStyle}
|
||||
import code.api.util.APIUtil.{DateWithDay, DateWithSeconds, gitCommit, stringOptionOrNull, stringOrNull}
|
||||
import code.api.v1_2_1.JSONFactory.{createAmountOfMoneyJSON, createOwnersJSON}
|
||||
import code.api.v1_2_1.{BankRoutingJsonV121, JSONFactory, UserJSONV121, ViewJSONV121}
|
||||
@ -2049,6 +2049,19 @@ object JSONFactory400 {
|
||||
created_by_user_id = wh.createdByUserId
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def getView(bankId: BankId, accountId: AccountId, postView: PostViewJsonV400, callContext: Option[CallContext]) = {
|
||||
postView.is_system match {
|
||||
case true => NewStyle.function.systemView(ViewId(postView.view_id), callContext)
|
||||
case false => NewStyle.function.customView(ViewId(postView.view_id), BankIdAccountId(bankId, accountId), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
def grantAccountAccessToUser(bankId: BankId, accountId: AccountId, user: User, view: View, callContext: Option[CallContext]) = {
|
||||
view.isSystem match {
|
||||
case true => NewStyle.function.grantAccessToSystemView(bankId, accountId, view, user, callContext)
|
||||
case false => NewStyle.function.grantAccessToCustomView(view, user, callContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ import code.api.v3_0_0.JSONFactory300
|
||||
import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson
|
||||
import code.api.v3_1_0.ConsentJsonV310
|
||||
import code.api.v3_1_0.JSONFactory310.createBadLoginStatusJson
|
||||
import code.api.v4_0_0.{JSONFactory400, PostApiCollectionJson400}
|
||||
import code.api.v4_0_0.{JSONFactory400, PostAccountAccessJsonV400, PostApiCollectionJson400}
|
||||
import code.api.v5_1_0.JSONFactory510.{createRegulatedEntitiesJson, createRegulatedEntityJson}
|
||||
import code.atmattribute.AtmAttribute
|
||||
import code.bankconnectors.Connector
|
||||
@ -1919,6 +1919,57 @@ trait APIMethods510 {
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
grantUserAccessToViewById,
|
||||
implementedInApiVersion,
|
||||
nameOf(grantUserAccessToViewById),
|
||||
"POST",
|
||||
"/banks/BANK_ID/accounts/ACCOUNT_ID/VIEW_ID/account-access/grant",
|
||||
"Grant User access to View By Id",
|
||||
s"""Grants the User identified by USER_ID access to the view identified by VIEW_ID.
|
||||
|
|
||||
|${authenticationRequiredMessage(true)} and the user needs to be account holder.
|
||||
|
|
||||
|""",
|
||||
postAccountAccessJsonV400,
|
||||
viewJsonV300,
|
||||
List(
|
||||
$UserNotLoggedIn,
|
||||
UserLacksPermissionCanGrantAccessToViewForTargetAccount,
|
||||
InvalidJsonFormat,
|
||||
UserNotFoundById,
|
||||
SystemViewNotFound,
|
||||
ViewNotFound,
|
||||
CannotGrantAccountAccess,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagAccountAccess, apiTagView, apiTagAccount, apiTagUser, apiTagOwnerRequired))
|
||||
|
||||
lazy val grantUserAccessToViewById: OBPEndpoint = {
|
||||
//add access for specific user to a specific system view
|
||||
case "banks" :: BankId(bankId) :: "accounts" :: AccountId(accountId) :: ViewId(viewId):: "account-access" :: "grant" :: Nil JsonPost json -> _ => {
|
||||
cc =>
|
||||
implicit val ec = EndpointContext(Some(cc))
|
||||
val failMsg = s"$InvalidJsonFormat The Json body should be the $PostAccountAccessJsonV400 "
|
||||
for {
|
||||
(Full(u), callContext) <- SS.user
|
||||
postJson <- NewStyle.function.tryons(failMsg, 400, cc.callContext) {
|
||||
json.extract[PostAccountAccessJsonV400]
|
||||
}
|
||||
_ <- Helper.booleanToFuture(s"$UserLacksPermissionCanGrantAccessToViewForTargetAccount Current ViewId(${viewId.value}), Target ViewId(${postJson.view.view_id}))", cc = cc.callContext) {
|
||||
APIUtil.canGrantAccessToView(BankIdAccountIdViewId(bankId,accountId,viewId),ViewId(postJson.view.view_id), u, callContext)
|
||||
}
|
||||
(user, callContext) <- NewStyle.function.findByUserId(postJson.user_id, callContext)
|
||||
view <- JSONFactory400.getView(bankId, accountId, postJson.view, callContext)
|
||||
addedView <- JSONFactory400.grantAccountAccessToUser(bankId, accountId, user, view, callContext)
|
||||
|
||||
} yield {
|
||||
val viewJson = JSONFactory300.createViewJSON(addedView)
|
||||
(viewJson, HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ object AkkaConnectorActorConfig {
|
||||
"code.model.dataAccess.ViewImpl" = kryo,
|
||||
"com.openbankproject.commons.model.User" = kryo,
|
||||
"com.openbankproject.commons.model.ViewId" = kryo,
|
||||
"com.openbankproject.commons.model.ViewIdBankIdAccountId" = kryo,
|
||||
"com.openbankproject.commons.model.BankIdAccountIdViewId" = kryo,
|
||||
"com.openbankproject.commons.model.Permission" = kryo,
|
||||
"scala.Unit" = kryo,
|
||||
"scala.Boolean" = kryo,
|
||||
|
||||
@ -40,7 +40,7 @@ import code.util.Helper
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.views.Views
|
||||
import code.views.system.AccountAccess
|
||||
import com.openbankproject.commons.model.{AccountId, AccountRouting, Attribute, Bank, BankAccount, BankAccountCommons, BankId, BankIdAccountId, Counterparty, CounterpartyId, CounterpartyTrait, CreateViewJson, Customer, Permission, TransactionId, UpdateViewJSON, User, UserPrimaryKey, View, ViewId, ViewIdBankIdAccountId}
|
||||
import com.openbankproject.commons.model.{AccountId, AccountRouting, Attribute, Bank, BankAccount, BankAccountCommons, BankId, BankIdAccountId, Counterparty, CounterpartyId, CounterpartyTrait, CreateViewJson, Customer, Permission, TransactionId, UpdateViewJSON, User, UserPrimaryKey, View, ViewId, BankIdAccountIdViewId}
|
||||
import net.liftweb.common._
|
||||
import net.liftweb.json.JsonDSL._
|
||||
import net.liftweb.json.{JArray, JObject}
|
||||
@ -218,9 +218,9 @@ case class BankAccountExtended(val bankAccount: BankAccount) extends MdcLoggable
|
||||
* @param otherUserIdGivenByProvider the id of the user (the one given by their auth provider) to whom access to the view will be granted
|
||||
* @return a Full(true) if everything is okay, a Failure otherwise
|
||||
*/
|
||||
final def grantAccessToView(user : User, viewUID : ViewIdBankIdAccountId, otherUserProvider : String, otherUserIdGivenByProvider: String, callContext: Option[CallContext]) : Box[View] = {
|
||||
final def grantAccessToView(user : User, viewUID : BankIdAccountIdViewId, otherUserProvider : String, otherUserIdGivenByProvider: String, callContext: Option[CallContext]) : Box[View] = {
|
||||
def grantAccessToCustomOrSystemView(user: User): Box[View] = {
|
||||
val ViewIdBankIdAccountId(viewId, bankId, accountId) = viewUID
|
||||
val BankIdAccountIdViewId(bankId, accountId, viewId) = viewUID
|
||||
Views.views.vend.systemView(viewId) match {
|
||||
case Full(systemView) => Views.views.vend.grantAccessToSystemView(bankId, accountId, systemView, user)
|
||||
case _ => Views.views.vend.grantAccessToCustomView(viewUID, user)
|
||||
@ -242,7 +242,7 @@ case class BankAccountExtended(val bankAccount: BankAccount) extends MdcLoggable
|
||||
* @param otherUserIdGivenByProvider the id of the user (the one given by their auth provider) to whom access to the views will be granted
|
||||
* @return a the list of the granted views if everything is okay, a Failure otherwise
|
||||
*/
|
||||
final def grantAccessToMultipleViews(user : User, viewUIDs : List[ViewIdBankIdAccountId], otherUserProvider : String, otherUserIdGivenByProvider: String,
|
||||
final def grantAccessToMultipleViews(user : User, viewUIDs : List[BankIdAccountIdViewId], otherUserProvider : String, otherUserIdGivenByProvider: String,
|
||||
callContext: Option[CallContext]) : Box[List[View]] = {
|
||||
if(canGrantAccessToMultipleViews(bankId, accountId, viewUIDs.map(_.viewId), user, callContext))
|
||||
for{
|
||||
@ -260,9 +260,9 @@ case class BankAccountExtended(val bankAccount: BankAccount) extends MdcLoggable
|
||||
* @param otherUserIdGivenByProvider the id of the user (the one given by their auth provider) to whom access to the view will be revoked
|
||||
* @return a Full(true) if everything is okay, a Failure otherwise
|
||||
*/
|
||||
final def revokeAccessToView(user : User, viewUID : ViewIdBankIdAccountId, otherUserProvider : String, otherUserIdGivenByProvider: String, callContext: Option[CallContext]) : Box[Boolean] = {
|
||||
final def revokeAccessToView(user : User, viewUID : BankIdAccountIdViewId, otherUserProvider : String, otherUserIdGivenByProvider: String, callContext: Option[CallContext]) : Box[Boolean] = {
|
||||
def revokeAccessToCustomOrSystemView(user: User): Box[Boolean] = {
|
||||
val ViewIdBankIdAccountId(viewId, bankId, accountId) = viewUID
|
||||
val BankIdAccountIdViewId(bankId, accountId, viewId) = viewUID
|
||||
Views.views.vend.systemView(viewId) match {
|
||||
case Full(systemView) => Views.views.vend.revokeAccessToSystemView(bankId, accountId, systemView, user)
|
||||
case _ => Views.views.vend.revokeAccess(viewUID, user)
|
||||
|
||||
@ -1511,8 +1511,8 @@ def restoreSomeSessions(): Unit = {
|
||||
cbsRemovedViewsForAccount = obpViewsForAccount diff cbsViewsForAccount
|
||||
_ = logger.debug("refreshViewsAccountAccessAndHolders.cbsRemovedViewsForAccount-------" + cbsRemovedViewsForAccount)
|
||||
_ = if(cbsRemovedViewsForAccount.nonEmpty){
|
||||
val cbsRemovedViewIdBankIdAccountIds = cbsRemovedViewsForAccount.map(view => ViewIdBankIdAccountId(ViewId(view), bankAccountId.bankId, bankAccountId.accountId))
|
||||
Views.views.vend.revokeAccessToMultipleViews(cbsRemovedViewIdBankIdAccountIds, user)
|
||||
val cbsRemovedBankIdAccountIdViewIds = cbsRemovedViewsForAccount.map(view => BankIdAccountIdViewId(bankAccountId.bankId, bankAccountId.accountId, ViewId(view)))
|
||||
Views.views.vend.revokeAccessToMultipleViews(cbsRemovedBankIdAccountIdViewIds, user)
|
||||
cbsRemovedViewsForAccount.map(view =>Views.views.vend.removeCustomView(ViewId(view), bankAccountId))
|
||||
UserRefreshes.UserRefreshes.vend.createOrUpdateRefreshUser(user.userId)
|
||||
}
|
||||
|
||||
@ -15,32 +15,36 @@ object RemotedataViews extends ObpActorInit with Views {
|
||||
|
||||
val cc = RemotedataViewsCaseClasses
|
||||
|
||||
def grantAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User, callContext: Option[CallContext]): Box[List[View]] = getValueFromFuture(
|
||||
def grantAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User, callContext: Option[CallContext]): Box[List[View]] = getValueFromFuture(
|
||||
(actor ? cc.grantAccessToMultipleViews(views, user, callContext)).mapTo[Box[List[View]]]
|
||||
)
|
||||
|
||||
def revokeAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User): Box[List[View]] = getValueFromFuture(
|
||||
def revokeAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User): Box[List[View]] = getValueFromFuture(
|
||||
(actor ? cc.revokeAccessToMultipleViews(views, user)).mapTo[Box[List[View]]]
|
||||
)
|
||||
|
||||
def permission(account: BankIdAccountId, user: User): Box[Permission] = getValueFromFuture(
|
||||
(actor ? cc.permission(account, user)).mapTo[Box[Permission]]
|
||||
)
|
||||
|
||||
def getViewByBankIdAccountIdViewIdUserPrimaryKey(bankIdAccountIdViewId: BankIdAccountIdViewId, userPrimaryKey: UserPrimaryKey): Box[View] = getValueFromFuture(
|
||||
(actor ? cc.getViewBydBankIdAccountIdViewIdAndUser(bankIdAccountIdViewId: BankIdAccountIdViewId, userPrimaryKey: UserPrimaryKey)).mapTo[Box[View]]
|
||||
)
|
||||
|
||||
def getPermissionForUser(user: User): Box[Permission] = getValueFromFuture(
|
||||
(actor ? cc.getPermissionForUser(user)).mapTo[Box[Permission]]
|
||||
)
|
||||
|
||||
def grantAccessToCustomView(viewIdBankIdAccountId: ViewIdBankIdAccountId, user: User): Box[View] = getValueFromFuture(
|
||||
(actor ? cc.addPermission(viewIdBankIdAccountId, user)).mapTo[Box[View]]
|
||||
def grantAccessToCustomView(bankIdAccountIdViewId: BankIdAccountIdViewId, user: User): Box[View] = getValueFromFuture(
|
||||
(actor ? cc.addPermission(bankIdAccountIdViewId, user)).mapTo[Box[View]]
|
||||
)
|
||||
|
||||
def grantAccessToSystemView(bankId: BankId, accountId: AccountId, view: View, user: User): Box[View] = getValueFromFuture(
|
||||
(actor ? cc.addSystemViewPermission(bankId, accountId, view, user)).mapTo[Box[View]]
|
||||
)
|
||||
|
||||
def revokeAccess(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[Boolean] = getValueFromFuture(
|
||||
(actor ? cc.revokeAccess(viewIdBankIdAccountId, user)).mapTo[Box[Boolean]]
|
||||
def revokeAccess(bankIdAccountIdViewId : BankIdAccountIdViewId, user : User) : Box[Boolean] = getValueFromFuture(
|
||||
(actor ? cc.revokeAccess(bankIdAccountIdViewId, user)).mapTo[Box[Boolean]]
|
||||
)
|
||||
|
||||
def revokeAccessToSystemView(bankId: BankId, accountId: AccountId, view : View, user : User) : Box[Boolean] = getValueFromFuture(
|
||||
|
||||
@ -18,9 +18,9 @@ class RemotedataViewsActor extends Actor with ObpActorHelper with MdcLoggable {
|
||||
|
||||
def receive: PartialFunction[Any, Unit] = {
|
||||
|
||||
case cc.addPermission(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) =>
|
||||
logger.debug("addPermission(" + viewIdBankIdAccountId +"," + user +")")
|
||||
sender ! (mapper.grantAccessToCustomView(viewIdBankIdAccountId, user))
|
||||
case cc.addPermission(bankIdAccountIdViewId : BankIdAccountIdViewId, user : User) =>
|
||||
logger.debug("addPermission(" + bankIdAccountIdViewId +"," + user +")")
|
||||
sender ! (mapper.grantAccessToCustomView(bankIdAccountIdViewId, user))
|
||||
|
||||
case cc.addSystemViewPermission(bankId: BankId, accountId: AccountId, view : View, user : User) =>
|
||||
logger.debug("addSystemViewPermission(" + bankId +"," + accountId +"," + view +"," + user +")")
|
||||
|
||||
@ -86,6 +86,16 @@ object MapperViews extends Views with MdcLoggable {
|
||||
Full(Permission(user, getViewsForUserAndAccount(user, account)))
|
||||
}
|
||||
|
||||
def getViewByBankIdAccountIdViewIdUserPrimaryKey(bankIdAccountIdViewId: BankIdAccountIdViewId, userPrimaryKey: UserPrimaryKey): Box[View] = {
|
||||
val accountAccessList = AccountAccess.findByBankIdAccountIdViewIdUserPrimaryKey(
|
||||
bankId = bankIdAccountIdViewId.bankId,
|
||||
accountId = bankIdAccountIdViewId.accountId,
|
||||
viewId = bankIdAccountIdViewId.viewId,
|
||||
userPrimaryKey = userPrimaryKey
|
||||
)
|
||||
accountAccessList.map(getViewFromAccountAccess).flatten
|
||||
}
|
||||
|
||||
def getPermissionForUser(user: User): Box[Permission] = {
|
||||
Full(Permission(user, getViewsForUser(user)))
|
||||
}
|
||||
@ -124,11 +134,11 @@ object MapperViews extends Views with MdcLoggable {
|
||||
getOrGrantAccessToViewCommon(user, view, bankId.value, accountId.value)
|
||||
}
|
||||
// TODO Accept the whole view as a parameter so we don't have to select it here.
|
||||
def grantAccessToCustomView(viewIdBankIdAccountId: ViewIdBankIdAccountId, user: User): Box[View] = {
|
||||
logger.debug(s"addPermission says viewUID is $viewIdBankIdAccountId user is $user")
|
||||
val viewId = viewIdBankIdAccountId.viewId.value
|
||||
val bankId = viewIdBankIdAccountId.bankId.value
|
||||
val accountId = viewIdBankIdAccountId.accountId.value
|
||||
def grantAccessToCustomView(bankIdAccountIdViewId: BankIdAccountIdViewId, user: User): Box[View] = {
|
||||
logger.debug(s"addPermission says viewUID is $bankIdAccountIdViewId user is $user")
|
||||
val viewId = bankIdAccountIdViewId.viewId.value
|
||||
val bankId = bankIdAccountIdViewId.bankId.value
|
||||
val accountId = bankIdAccountIdViewId.accountId.value
|
||||
val viewDefinition = ViewDefinition.findCustomView(bankId, accountId, viewId)
|
||||
|
||||
viewDefinition match {
|
||||
@ -136,10 +146,10 @@ object MapperViews extends Views with MdcLoggable {
|
||||
if(v.isPublic && !allowPublicViews) return Failure(PublicViewsNotAllowedOnThisInstance)
|
||||
// SQL Select Count AccountAccessList where
|
||||
// This is idempotent
|
||||
getOrGrantAccessToViewCommon(user, v, viewIdBankIdAccountId.bankId.value, viewIdBankIdAccountId.accountId.value) //accountAccess already exists, no need to create one
|
||||
getOrGrantAccessToViewCommon(user, v, bankIdAccountIdViewId.bankId.value, bankIdAccountIdViewId.accountId.value) //accountAccess already exists, no need to create one
|
||||
}
|
||||
case _ => {
|
||||
Empty ~> APIFailure(s"View $viewIdBankIdAccountId. not found", 404) //TODO: move message + code logic to api level
|
||||
Empty ~> APIFailure(s"View $bankIdAccountIdViewId. not found", 404) //TODO: move message + code logic to api level
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,8 +160,8 @@ object MapperViews extends Views with MdcLoggable {
|
||||
}
|
||||
}
|
||||
|
||||
def grantAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User, callContext: Option[CallContext]): Box[List[View]] = {
|
||||
val viewDefinitions: List[(ViewDefinition, ViewIdBankIdAccountId)] = views.map {
|
||||
def grantAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User, callContext: Option[CallContext]): Box[List[View]] = {
|
||||
val viewDefinitions: List[(ViewDefinition, BankIdAccountIdViewId)] = views.map {
|
||||
uid => ViewDefinition.findCustomView(uid.bankId.value,uid.accountId.value, uid.viewId.value).map((_, uid))
|
||||
.or(ViewDefinition.findSystemView(uid.viewId.value).map((_, uid)))
|
||||
}.collect { case Full(v) => v}
|
||||
@ -166,15 +176,15 @@ object MapperViews extends Views with MdcLoggable {
|
||||
viewDefinitions.foreach(v => {
|
||||
if(v._1.isPublic && !allowPublicViews) return Failure(PublicViewsNotAllowedOnThisInstance)
|
||||
val viewDefinition = v._1
|
||||
val viewIdBankIdAccountId = v._2
|
||||
val bankIdAccountIdViewId = v._2
|
||||
// This is idempotent
|
||||
getOrGrantAccessToViewCommon(user, viewDefinition, viewIdBankIdAccountId.bankId.value, viewIdBankIdAccountId.accountId.value)
|
||||
getOrGrantAccessToViewCommon(user, viewDefinition, bankIdAccountIdViewId.bankId.value, bankIdAccountIdViewId.accountId.value)
|
||||
})
|
||||
Full(viewDefinitions.map(_._1))
|
||||
}
|
||||
}
|
||||
def revokeAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User): Box[List[View]] = {
|
||||
val viewDefinitions: List[(ViewDefinition, ViewIdBankIdAccountId)] = views.map {
|
||||
def revokeAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User): Box[List[View]] = {
|
||||
val viewDefinitions: List[(ViewDefinition, BankIdAccountIdViewId)] = views.map {
|
||||
uid => ViewDefinition.findCustomView(uid.bankId.value,uid.accountId.value, uid.viewId.value).map((_, uid))
|
||||
.or(ViewDefinition.findSystemView(uid.viewId.value).map((_, uid)))
|
||||
}.collect { case Full(v) => v}
|
||||
@ -195,14 +205,14 @@ object MapperViews extends Views with MdcLoggable {
|
||||
}
|
||||
}
|
||||
|
||||
def revokeAccess(viewUID : ViewIdBankIdAccountId, user : User) : Box[Boolean] = {
|
||||
def revokeAccess(bankIdAccountIdViewId : BankIdAccountIdViewId, user : User) : Box[Boolean] = {
|
||||
val isRevokedCustomViewAccess =
|
||||
for {
|
||||
customViewDefinition <- ViewDefinition.findCustomView(viewUID.bankId.value, viewUID.accountId.value, viewUID.viewId.value)
|
||||
customViewDefinition <- ViewDefinition.findCustomView(bankIdAccountIdViewId.bankId.value, bankIdAccountIdViewId.accountId.value, bankIdAccountIdViewId.viewId.value)
|
||||
accountAccess <- AccountAccess.findByBankIdAccountIdViewIdUserPrimaryKey(
|
||||
viewUID.bankId,
|
||||
viewUID.accountId,
|
||||
viewUID.viewId,
|
||||
bankIdAccountIdViewId.bankId,
|
||||
bankIdAccountIdViewId.accountId,
|
||||
bankIdAccountIdViewId.viewId,
|
||||
user.userPrimaryKey
|
||||
) ?~! CannotFindAccountAccess
|
||||
} yield {
|
||||
@ -211,15 +221,15 @@ object MapperViews extends Views with MdcLoggable {
|
||||
|
||||
val isRevokedSystemViewAccess =
|
||||
for {
|
||||
systemViewDefinition <- ViewDefinition.findSystemView(viewUID.viewId.value)
|
||||
systemViewDefinition <- ViewDefinition.findSystemView(bankIdAccountIdViewId.viewId.value)
|
||||
accountAccess <- AccountAccess.findByBankIdAccountIdViewIdUserPrimaryKey(
|
||||
viewUID.bankId,
|
||||
viewUID.accountId,
|
||||
viewUID.viewId,
|
||||
bankIdAccountIdViewId.bankId,
|
||||
bankIdAccountIdViewId.accountId,
|
||||
bankIdAccountIdViewId.viewId,
|
||||
user.userPrimaryKey
|
||||
) ?~! CannotFindAccountAccess
|
||||
// Check if we are allowed to remove the View from the User
|
||||
_ <- canRevokeOwnerAccessAsBox(viewUID.bankId, viewUID.accountId,systemViewDefinition, user)
|
||||
_ <- canRevokeOwnerAccessAsBox(bankIdAccountIdViewId.bankId, bankIdAccountIdViewId.accountId,systemViewDefinition, user)
|
||||
} yield {
|
||||
accountAccess.delete_!
|
||||
}
|
||||
|
||||
@ -34,16 +34,16 @@ trait Views {
|
||||
def permissions(account : BankIdAccountId) : List[Permission]
|
||||
def permission(account : BankIdAccountId, user: User) : Box[Permission]
|
||||
def getPermissionForUser(user: User) : Box[Permission]
|
||||
/**
|
||||
/**
|
||||
* This is for @ViewPrivileges.
|
||||
* It will first find the view object by `viewIdBankIdAccountId`
|
||||
* It will first find the view object by `bankIdAccountIdViewId`
|
||||
* And then, call @getOrCreateViewPrivilege(view: View, user: User) for the view and user.
|
||||
*/
|
||||
def grantAccessToCustomView(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[View]
|
||||
def grantAccessToCustomView(bankIdAccountIdViewId : BankIdAccountIdViewId, user : User) : Box[View]
|
||||
def grantAccessToSystemView(bankId: BankId, accountId: AccountId, view : View, user : User) : Box[View]
|
||||
def grantAccessToMultipleViews(views : List[ViewIdBankIdAccountId], user : User, callContext: Option[CallContext]) : Box[List[View]]
|
||||
def revokeAccessToMultipleViews(views : List[ViewIdBankIdAccountId], user : User) : Box[List[View]]
|
||||
def revokeAccess(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[Boolean]
|
||||
def grantAccessToMultipleViews(views : List[BankIdAccountIdViewId], user : User, callContext: Option[CallContext]) : Box[List[View]]
|
||||
def revokeAccessToMultipleViews(views : List[BankIdAccountIdViewId], user : User) : Box[List[View]]
|
||||
def revokeAccess(bankIdAccountIdViewId : BankIdAccountIdViewId, user : User) : Box[Boolean]
|
||||
def revokeAccessToSystemView(bankId: BankId, accountId: AccountId, view : View, user : User) : Box[Boolean]
|
||||
def revokeAllAccountAccess(bankId : BankId, accountId : AccountId, user : User) : Box[Boolean]
|
||||
def revokeAccountAccessByUser(bankId : BankId, accountId : AccountId, user : User, callContext: Option[CallContext]) : Box[Boolean]
|
||||
@ -56,6 +56,7 @@ trait Views {
|
||||
def customViewFuture(viewId : ViewId, bankAccountId: BankIdAccountId) : Future[Box[View]]
|
||||
def systemViewFuture(viewId : ViewId) : Future[Box[View]]
|
||||
def getSystemViews(): Future[List[View]]
|
||||
def getViewByBankIdAccountIdViewIdUserPrimaryKey(bankIdAccountIdViewId : BankIdAccountIdViewId, userPrimaryKey: UserPrimaryKey) : Box[View]
|
||||
|
||||
//always return a view id String, not error here.
|
||||
def getMetadataViewId(bankAccountId: BankIdAccountId, viewId : ViewId) = Views.views.vend.customView(viewId, bankAccountId).map(_.metadataView).openOr(viewId.value)
|
||||
@ -128,11 +129,12 @@ class RemotedataViewsCaseClasses {
|
||||
case class permissions(account: BankIdAccountId)
|
||||
case class getPermissionForUser(user: User)
|
||||
case class permission(account: BankIdAccountId, user: User)
|
||||
case class addPermission(viewUID: ViewIdBankIdAccountId, user: User)
|
||||
case class getViewBydBankIdAccountIdViewIdAndUser(bankIdAccountIdViewId: BankIdAccountIdViewId, userPrimaryKey: UserPrimaryKey)
|
||||
case class addPermission(viewUID: BankIdAccountIdViewId, user: User)
|
||||
case class addSystemViewPermission(bankId: BankId, accountId: AccountId, view : View, user : User)
|
||||
case class revokeAccess(viewIdBankIdAccountId: ViewIdBankIdAccountId, user : User)
|
||||
case class grantAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User, callContext: Option[CallContext])
|
||||
case class revokeAccessToMultipleViews(views: List[ViewIdBankIdAccountId], user: User)
|
||||
case class revokeAccess(bankIdAccountIdViewId: BankIdAccountIdViewId, user : User)
|
||||
case class grantAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User, callContext: Option[CallContext])
|
||||
case class revokeAccessToMultipleViews(views: List[BankIdAccountIdViewId], user: User)
|
||||
case class revokeSystemViewPermission(bankId: BankId, accountId: AccountId, view : View, user : User)
|
||||
case class revokeAllAccountAccess(bankId: BankId, accountId: AccountId, user: User)
|
||||
case class revokeAccountAccessByUser(bankId: BankId, accountId: AccountId, user: User, callContext: Option[CallContext])
|
||||
|
||||
@ -1396,7 +1396,7 @@
|
||||
// val bankId = randomBank
|
||||
// val bankAccount : AccountJSON = randomPrivateAccount(bankId)
|
||||
// val viewId = ViewId("owner")
|
||||
// val view = Views.views.vend.view(ViewIdBankIdAccountId(viewId, BankId(bankId), AccountId(bankAccount.id))).get
|
||||
// val view = Views.views.vend.view(BankIdAccountIdViewId(BankId(bankId), AccountId(bankAccount.id), viewId)).get
|
||||
// if(Views.views.vend.getOwners(view).toList.length == 0){
|
||||
// val userId = resourceUser2.idGivenByProvider
|
||||
// grantUserAccessToView(bankId, bankAccount.id, userId, viewId.value, user1)
|
||||
|
||||
@ -7,7 +7,7 @@ import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ErrorMessages
|
||||
import code.setup.DefaultUsers
|
||||
import code.views.Views
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, ViewId, ViewIdBankIdAccountId}
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, ViewId, BankIdAccountIdViewId}
|
||||
import net.liftweb.json.JsonAST._
|
||||
import net.liftweb.json.Serialization.write
|
||||
|
||||
@ -90,7 +90,7 @@ class CreateCounterpartyTest extends V220ServerSetup with DefaultUsers {
|
||||
val bankId = testBank.bankId
|
||||
val accountId = AccountId("notExistingAccountId")
|
||||
val viewId =ViewId(SYSTEM_OWNER_VIEW_ID)
|
||||
Views.views.vend.grantAccessToCustomView(ViewIdBankIdAccountId(viewId, bankId, accountId), resourceUser1)
|
||||
Views.views.vend.grantAccessToCustomView(BankIdAccountIdViewId(bankId, accountId, viewId), resourceUser1)
|
||||
|
||||
val counterpartyPostJSON = SwaggerDefinitionsJSON.postCounterpartyJSON.copy(other_bank_routing_address=bankId.value,other_account_routing_address=accountId.value)
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import code.api.v4_0_0.OBPAPI4_0_0.Implementations4_0_0
|
||||
import code.entitlement.Entitlement
|
||||
import code.views.Views
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.{AccountId, ErrorMessage, ViewId, ViewIdBankIdAccountId}
|
||||
import com.openbankproject.commons.model.{AccountId, ErrorMessage, ViewId, BankIdAccountIdViewId}
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
138
obp-api/src/test/scala/code/api/v5_1_0/AccountAccessTest.scala
Normal file
138
obp-api/src/test/scala/code/api/v5_1_0/AccountAccessTest.scala
Normal file
@ -0,0 +1,138 @@
|
||||
package code.api.v5_1_0
|
||||
|
||||
import code.api.Constant.{SYSTEM_AUDITOR_VIEW_ID, SYSTEM_MANAGE_CUSTOM_VIEWS_VIEW_ID, SYSTEM_OWNER_VIEW_ID}
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.createViewJsonV300
|
||||
import code.api.util.APIUtil.OAuth._
|
||||
import code.api.util.ApiRole
|
||||
import code.api.util.ErrorMessages.{UserLacksPermissionCanGrantAccessToViewForTargetAccount, UserNotLoggedIn}
|
||||
import code.api.v3_0_0.ViewJsonV300
|
||||
import code.api.v3_1_0.CreateAccountResponseJsonV310
|
||||
import code.api.v4_0_0.{PostAccountAccessJsonV400, PostViewJsonV400}
|
||||
import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0
|
||||
import code.entitlement.Entitlement
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.{AmountOfMoneyJsonV121, ErrorMessage}
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
class AccountAccessTest extends V510ServerSetup {
|
||||
/**
|
||||
* Test tags
|
||||
* Example: To run tests with tag "getPermissions":
|
||||
* mvn test -D tagsToInclude
|
||||
*
|
||||
* This is made possible by the scalatest maven plugin
|
||||
*/
|
||||
object VersionOfApi extends Tag(ApiVersion.v5_1_0.toString)
|
||||
object ApiEndpoint1 extends Tag(nameOf(Implementations5_1_0.grantUserAccessToViewById))
|
||||
|
||||
|
||||
lazy val bankId = randomBankId
|
||||
lazy val bankAccount = randomPrivateAccountViaEndpoint(bankId)
|
||||
lazy val ownerView = SYSTEM_OWNER_VIEW_ID
|
||||
lazy val managerCustomView = SYSTEM_MANAGE_CUSTOM_VIEWS_VIEW_ID
|
||||
lazy val postAccountAccessJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400("_test_view", false))
|
||||
lazy val postBodyViewJson = createViewJsonV300.toCreateViewJson
|
||||
|
||||
def createAnAccount(bankId: String, user: Option[(Consumer,Token)]): CreateAccountResponseJsonV310 = {
|
||||
val addAccountJson = SwaggerDefinitionsJSON.createAccountRequestJsonV310.copy(user_id = resourceUser1.userId, balance = AmountOfMoneyJsonV121("EUR","0"))
|
||||
val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" ).POST <@(user1)
|
||||
val response510 = makePostRequest(request510, write(addAccountJson))
|
||||
Then("We should get a 201")
|
||||
|
||||
response510.code should equal(201)
|
||||
response510.body.extract[CreateAccountResponseJsonV310]
|
||||
}
|
||||
|
||||
def createViewForAnAccount(bankId: String, accountId: String): ViewJsonV300 = {
|
||||
createViewViaEndpoint(bankId, accountId, postBodyViewJson, user1)
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint1 Authorized access") {
|
||||
|
||||
scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v4.0.0")
|
||||
val request510 = (v5_1_0_Request / "banks" / bankId / "accounts" / bankAccount.id / ownerView /"account-access" / "grant").POST
|
||||
val response510 = makePostRequest(request510, write(postAccountAccessJson))
|
||||
Then("We should get a 401")
|
||||
response510.code should equal(401)
|
||||
response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
|
||||
scenario("We will call the endpoint with user credentials and system view, but try to grant custom view access", VersionOfApi, ApiEndpoint1) {
|
||||
val addedEntitlement: Box[Entitlement] = Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, ApiRole.CanCreateAccount.toString)
|
||||
val account = try {
|
||||
createAnAccount(bankId, user1)
|
||||
} finally {
|
||||
Entitlement.entitlement.vend.deleteEntitlement(addedEntitlement)
|
||||
}
|
||||
|
||||
val view = createViewForAnAccount(bankId, account.account_id)
|
||||
val postJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400(view.id, view.is_system))
|
||||
When("We send the request")
|
||||
val request = (v5_1_0_Request / "banks" / bankId / "accounts" / account.account_id / ownerView / "account-access" / "grant").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(postJson))
|
||||
Then("We should get a 400 and check the response body")
|
||||
response.code should equal(400)
|
||||
response.body.toString.contains(UserLacksPermissionCanGrantAccessToViewForTargetAccount)
|
||||
}
|
||||
|
||||
scenario("We will call the endpoint with user credentials and managerCustomView view, but try to grant system view access", VersionOfApi, ApiEndpoint1) {
|
||||
val addedEntitlement: Box[Entitlement] = Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, ApiRole.CanCreateAccount.toString)
|
||||
val account = try {
|
||||
createAnAccount(bankId, user1)
|
||||
} finally {
|
||||
Entitlement.entitlement.vend.deleteEntitlement(addedEntitlement)
|
||||
}
|
||||
|
||||
val postJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400(SYSTEM_AUDITOR_VIEW_ID, true))
|
||||
When("We send the request")
|
||||
val request = (v5_1_0_Request / "banks" / bankId / "accounts" / account.account_id / managerCustomView / "account-access" / "grant").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(postJson))
|
||||
Then("We should get a 400 and check the response body")
|
||||
response.code should equal(400)
|
||||
response.body.toString.contains(UserLacksPermissionCanGrantAccessToViewForTargetAccount)
|
||||
}
|
||||
|
||||
scenario("We will call the endpoint with user credentials and system view permission", VersionOfApi, ApiEndpoint1) {
|
||||
val addedEntitlement: Box[Entitlement] = Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, ApiRole.CanCreateAccount.toString)
|
||||
val account = try {
|
||||
createAnAccount(bankId, user1)
|
||||
} finally {
|
||||
Entitlement.entitlement.vend.deleteEntitlement(addedEntitlement)
|
||||
}
|
||||
|
||||
val postJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400(SYSTEM_AUDITOR_VIEW_ID, true))
|
||||
When("We send the request")
|
||||
val request = (v5_1_0_Request / "banks" / bankId / "accounts" / account.account_id / ownerView / "account-access" / "grant").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(postJson))
|
||||
Then("We should get a 201 and check the response body")
|
||||
response.code should equal(201)
|
||||
response.body.extract[ViewJsonV300]
|
||||
}
|
||||
|
||||
scenario("We will call the endpoint with user credentials and custom view permission", VersionOfApi, ApiEndpoint1) {
|
||||
val addedEntitlement: Box[Entitlement] = Entitlement.entitlement.vend.addEntitlement(bankId, resourceUser1.userId, ApiRole.CanCreateAccount.toString)
|
||||
val account = try {
|
||||
createAnAccount(bankId, user1)
|
||||
} finally {
|
||||
Entitlement.entitlement.vend.deleteEntitlement(addedEntitlement)
|
||||
}
|
||||
|
||||
val view = createViewForAnAccount(bankId, account.account_id)
|
||||
val postJson = PostAccountAccessJsonV400(resourceUser2.userId, PostViewJsonV400(view.id, view.is_system))
|
||||
When("We send the request")
|
||||
val request = (v5_1_0_Request / "banks" / bankId / "accounts" / account.account_id / managerCustomView / "account-access" / "grant").POST <@ (user1)
|
||||
val response = makePostRequest(request, write(postJson))
|
||||
Then("We should get a 201 and check the response body")
|
||||
response.code should equal(201)
|
||||
response.body.extract[ViewJsonV300]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,15 +1,19 @@
|
||||
package code.api.v5_1_0
|
||||
|
||||
import code.api.Constant.SYSTEM_OWNER_VIEW_ID
|
||||
import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON
|
||||
import code.api.util.APIUtil.OAuth.{Consumer, Token, _}
|
||||
import code.api.util.ApiRole
|
||||
import code.api.util.ApiRole.CanCreateCustomer
|
||||
import code.api.v1_2_1.{AccountJSON, AccountsJSON, ViewsJSONV121}
|
||||
import code.api.v2_0_0.BasicAccountsJSON
|
||||
import code.api.v3_0_0.ViewJsonV300
|
||||
import code.api.v3_1_0.CustomerJsonV310
|
||||
import code.api.v4_0_0.{AtmJsonV400, BanksJson400}
|
||||
import code.api.v5_0_0.PostCustomerJsonV500
|
||||
import code.entitlement.Entitlement
|
||||
import code.setup.{APIResponse, DefaultUsers, ServerSetupWithTestData}
|
||||
import com.openbankproject.commons.model.CreateViewJson
|
||||
import com.openbankproject.commons.util.ApiShortVersions
|
||||
import dispatch.Req
|
||||
import net.liftweb.json.Serialization.write
|
||||
@ -34,6 +38,26 @@ trait V510ServerSetup extends ServerSetupWithTestData with DefaultUsers {
|
||||
val bank = banksJson.banks(randomPosition)
|
||||
bank.id
|
||||
}
|
||||
|
||||
def getPrivateAccountsViaEndpoint(bankId : String, consumerAndToken: Option[(Consumer, Token)]) : APIResponse = {
|
||||
val request = v5_1_0_Request / "banks" / bankId / "accounts" / "private" <@(consumerAndToken)
|
||||
makeGetRequest(request)
|
||||
}
|
||||
|
||||
def randomPrivateAccountViaEndpoint(bankId : String): AccountJSON = {
|
||||
val accountsJson = getPrivateAccountsViaEndpoint(bankId, user1).body.extract[AccountsJSON].accounts
|
||||
val randomPosition = nextInt(accountsJson.size)
|
||||
accountsJson(randomPosition)
|
||||
}
|
||||
|
||||
def createViewViaEndpoint(bankId: String, accountId: String, createViewJson: CreateViewJson, consumerAndToken: Option[(Consumer, Token)]): ViewJsonV300 = {
|
||||
def postView(bankId: String, accountId: String, view: CreateViewJson, consumerAndToken: Option[(Consumer, Token)]): APIResponse = {
|
||||
val request = (v4_0_0_Request / "banks" / bankId / "accounts" / accountId / "views").POST <@(consumerAndToken)
|
||||
makePostRequest(request, write(view))
|
||||
}
|
||||
val reply = postView(bankId, accountId, createViewJson, consumerAndToken)
|
||||
reply.body.extract[ViewJsonV300]
|
||||
}
|
||||
|
||||
def createAtmAtBank(bankId: String): AtmJsonV400 = {
|
||||
val postAtmJson = SwaggerDefinitionsJSON.atmJsonV400.copy(bank_id = bankId)
|
||||
|
||||
@ -65,8 +65,8 @@ trait Bank {
|
||||
/**
|
||||
* Uniquely identifies a view
|
||||
*/
|
||||
case class ViewIdBankIdAccountId(viewId : ViewId, bankId : BankId, accountId : AccountId) {
|
||||
override def toString = s"view $viewId, for account: $accountId at bank $bankId"
|
||||
case class BankIdAccountIdViewId(bankId : BankId, accountId : AccountId, viewId : ViewId) {
|
||||
override def toString = s"BankIdAccountIdViewId($bankId,$accountId,$viewId)"
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -218,7 +218,7 @@ trait View {
|
||||
def bankId: BankId
|
||||
|
||||
//and here is the unique identifier
|
||||
def uid: ViewIdBankIdAccountId = ViewIdBankIdAccountId(viewId, bankId, accountId)
|
||||
def uid: BankIdAccountIdViewId = BankIdAccountIdViewId(bankId, accountId, viewId)
|
||||
|
||||
//The name is the orignal value from developer, when they create the views.
|
||||
// It can be any string value, also see the viewId,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user