mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 19:36:50 +00:00
Add bank level entitlements / roles #42 - without item number 7
This commit is contained in:
parent
81d57c91bb
commit
7b2728e0cc
@ -170,3 +170,7 @@ apiOptions.getTransactionTypesIsPublic = true
|
||||
# Default Bank. Incase the server wants to support a default bank so developers don't have to specify BANK_ID
|
||||
# e.g. developers could use /my/accounts as well as /my/banks/BANK_ID/accounts
|
||||
defaultBank.bank_id=THE_DEFAULT_BANK_ID
|
||||
|
||||
|
||||
# Super Admin Users (not database so we don't have to edit database)
|
||||
super_admin_user_ids=USER_ID1,USER_ID2,
|
||||
@ -42,6 +42,7 @@ import code.atms.MappedAtm
|
||||
import code.branches.MappedBranch
|
||||
import code.crm.MappedCrmEvent
|
||||
import code.customer.{MappedCustomer, MappedCustomerMessage}
|
||||
import code.entitlement.MappedEntitlement
|
||||
import code.kycdocuments.MappedKycDocument
|
||||
import code.kycmedias.MappedKycMedia
|
||||
import code.kycchecks.MappedKycCheck
|
||||
@ -419,5 +420,6 @@ object ToSchemify {
|
||||
MappedSocialMedia,
|
||||
MappedTransactionType,
|
||||
MappedMeeting,
|
||||
MappedUserCustomerLink)
|
||||
MappedUserCustomerLink,
|
||||
MappedEntitlement)
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ package code.api.util
|
||||
|
||||
import code.api.Constant._
|
||||
import code.api.v1_2.ErrorMessage
|
||||
import code.entitlement.Entitlements
|
||||
import code.metrics.APIMetrics
|
||||
import code.model._
|
||||
import dispatch.url
|
||||
@ -572,4 +573,13 @@ object APIUtil extends Loggable {
|
||||
halLinksJson
|
||||
}
|
||||
|
||||
def isSuperAdmin(user_id: String) : Boolean = {
|
||||
val user_ids = Props.get("super_admin_user_ids", "super_admin_user_ids is not defined").split(",").map(_.trim).toList
|
||||
user_ids.filter(_ == user_id).length > 0
|
||||
}
|
||||
|
||||
def hasEntitlement(bankId: String, userId: String, role: ApiRole): Boolean = {
|
||||
Entitlements.entitlementProvider.vend.getEntitlement(bankId, userId, role.toString).isEmpty
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
18
src/main/scala/code/api/util/ApiRole.scala
Normal file
18
src/main/scala/code/api/util/ApiRole.scala
Normal file
@ -0,0 +1,18 @@
|
||||
package code.api.util
|
||||
|
||||
sealed trait ApiRole
|
||||
|
||||
object ApiRole {
|
||||
|
||||
case object CanSearchAllTransactions extends ApiRole
|
||||
case object CanSearchAllAccounts extends ApiRole
|
||||
case object CanQueryOtherUser extends ApiRole
|
||||
|
||||
def valueOf(value: String): ApiRole = value match {
|
||||
case "CanSearchAllTransactions" => CanSearchAllTransactions
|
||||
case "CanSearchAllAccounts" => CanSearchAllAccounts
|
||||
case "CanQueryOtherUser" => CanQueryOtherUser
|
||||
case _ => throw new IllegalArgumentException()
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ import java.util.Calendar
|
||||
import code.TransactionTypes.TransactionType
|
||||
import code.api.APIFailure
|
||||
import code.api.util.APIUtil._
|
||||
import code.api.util.ApiRole._
|
||||
import code.api.util.ErrorMessages
|
||||
import code.api.v1_2_1.OBPAPI1_2_1._
|
||||
import code.api.v1_2_1.{APIMethods121, AmountOfMoneyJSON => AmountOfMoneyJSON121, JSONFactory => JSONFactory121}
|
||||
@ -30,6 +31,7 @@ import code.transactionrequests.TransactionRequests
|
||||
|
||||
import code.meetings.Meeting
|
||||
import code.usercustomerlinks.UserCustomerLink
|
||||
import code.entitlement.Entitlements
|
||||
|
||||
import net.liftweb.common.{Full, _}
|
||||
import net.liftweb.http.rest.RestHelper
|
||||
@ -1614,8 +1616,79 @@ trait APIMethods200 {
|
||||
}
|
||||
}
|
||||
|
||||
resourceDocs += ResourceDoc(
|
||||
addEntitlements,
|
||||
apiVersion,
|
||||
"addEntitlements",
|
||||
"POST",
|
||||
"/users/USER_ID/entitlements",
|
||||
"Add role to specific user.",
|
||||
"""Grants the Role to user.
|
||||
|
|
||||
|OAuth authentication is required and the user needs to have access to the owner view.""",
|
||||
Extraction.decompose(CreateEntitlementJSON("obp-bank-x-gh", "CanQueryOtherUser")),
|
||||
emptyObjectJson,
|
||||
emptyObjectJson :: Nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
List())
|
||||
|
||||
lazy val addEntitlements : PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
//add access for specific user to a list of views
|
||||
case "users" :: userId :: "entitlements" :: Nil JsonPost json -> _ => {
|
||||
user =>
|
||||
for {
|
||||
u <- user ?~ ErrorMessages.UserNotLoggedIn
|
||||
isSuperAdmin <- booleanToBox(isSuperAdmin(u.userId)) ?~ "User is not super admin!"
|
||||
postedData <- tryo{json.extract[CreateEntitlementJSON]} ?~ "wrong format JSON"
|
||||
role <- tryo{valueOf(postedData.role_name)} ?~! "wrong role name"
|
||||
hasEntitlement <- booleanToBox(hasEntitlement(postedData.bank_id, u.userId, role)) ?~ "Entitlement already exists"
|
||||
addedEntitlement <- Entitlements.entitlementProvider.vend.addEntitlement(postedData.bank_id, u.userId, postedData.role_name)
|
||||
} yield {
|
||||
val viewJson = JSONFactory200.createEntitlementJSON(addedEntitlement)
|
||||
successJsonResponse(Extraction.decompose(viewJson), 201)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resourceDocs += ResourceDoc(
|
||||
getEntitlements,
|
||||
apiVersion,
|
||||
"getEntitlements",
|
||||
"GET",
|
||||
"/users/USER_ID/entitlements",
|
||||
"Get Entitlement specified by USER_ID",
|
||||
"""
|
||||
|
|
||||
|Login is required.
|
||||
|
|
||||
|
|
||||
""".stripMargin,
|
||||
emptyObjectJson,
|
||||
emptyObjectJson,
|
||||
emptyObjectJson :: Nil,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
List(apiTagMeeting, apiTagKyc, apiTagCustomer, apiTagUser, apiTagExperimental))
|
||||
|
||||
|
||||
lazy val getEntitlements: PartialFunction[Req, Box[User] => Box[JsonResponse]] = {
|
||||
case "users" :: userId :: "entitlements" :: Nil JsonGet _ => {
|
||||
user =>
|
||||
for {
|
||||
u <- user ?~ ErrorMessages.UserNotLoggedIn
|
||||
isSuperAdmin <- booleanToBox(isSuperAdmin(u.userId)) ?~ "User is not super admin!"
|
||||
entitlements <- Entitlements.entitlementProvider.vend.getEntitlements(u.userId)
|
||||
}
|
||||
yield {
|
||||
// Format the data as V2.0.0 json
|
||||
val json = JSONFactory200.createEntitlementJSONs(entitlements)
|
||||
successJsonResponse(Extraction.decompose(json))
|
||||
}
|
||||
}
|
||||
}
|
||||
///
|
||||
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import java.util.Date
|
||||
|
||||
import code.TransactionTypes.TransactionType.TransactionType
|
||||
import code.meetings.Meeting
|
||||
import code.entitlement.Entitlement
|
||||
import code.model.dataAccess.OBPUser
|
||||
import code.transactionrequests.TransactionRequests._
|
||||
import net.liftweb.common.{Full, Box}
|
||||
@ -310,6 +311,9 @@ case class TransactionRequestBodyJSON (
|
||||
description : String
|
||||
)
|
||||
|
||||
case class CreateEntitlementJSON(bank_id: String, role_name: String)
|
||||
case class EntitlementJSON(entitlement_id: String, user_id: String, role_name: String)
|
||||
case class EntitlementJSONs(list: List[EntitlementJSON])
|
||||
|
||||
object JSONFactory200{
|
||||
|
||||
@ -767,6 +771,16 @@ def createTransactionTypeJSON(transactionType : TransactionType) : TransactionTy
|
||||
UserCustomerLinkJSONs(ucls.map(createUserCustomerLinkJSON))
|
||||
}
|
||||
|
||||
def createEntitlementJSON(e: Entitlement): EntitlementJSON = {
|
||||
EntitlementJSON(entitlement_id = e.entitlementId,
|
||||
user_id = e.userId,
|
||||
role_name = e.roleName)
|
||||
}
|
||||
|
||||
def createEntitlementJSONs(l: List[Entitlement]) = {
|
||||
EntitlementJSONs(l.map(createEntitlementJSON))
|
||||
}
|
||||
|
||||
// Copied from 1.2.1 (import just this def instead?)
|
||||
def stringOrNull(text : String) =
|
||||
if(text == null || text.isEmpty)
|
||||
|
||||
@ -170,7 +170,9 @@ object OBPAPI2_0_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w
|
||||
Implementations2_0_0.getMeeting,
|
||||
Implementations2_0_0.createCustomer,
|
||||
Implementations2_0_0.getCurrentUser,
|
||||
Implementations2_0_0.createUserCustomerLinks
|
||||
Implementations2_0_0.createUserCustomerLinks,
|
||||
Implementations2_0_0.addEntitlements,
|
||||
Implementations2_0_0.getEntitlements
|
||||
)
|
||||
|
||||
routes.foreach(route => {
|
||||
|
||||
25
src/main/scala/code/entitlement/Entilement.scala
Normal file
25
src/main/scala/code/entitlement/Entilement.scala
Normal file
@ -0,0 +1,25 @@
|
||||
package code.entitlement
|
||||
|
||||
|
||||
import code.model.{BankId, User}
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.util.SimpleInjector
|
||||
|
||||
|
||||
object Entitlements extends SimpleInjector {
|
||||
val entitlementProvider = new Inject(buildOne _) {}
|
||||
def buildOne: EntitlementProvider = MappedEntitlementsProvider
|
||||
}
|
||||
|
||||
trait EntitlementProvider {
|
||||
def getEntitlement(bankId: String, userId: String, roleName: String) : Box[Entitlement]
|
||||
def getEntitlements(userId: String) : Box[List[Entitlement]]
|
||||
def addEntitlement(bankId: String, userId: String, roleName: String) : Box[MappedEntitlement]
|
||||
}
|
||||
|
||||
trait Entitlement {
|
||||
def entitlementId: String
|
||||
def bankId : String
|
||||
def userId : String
|
||||
def roleName : String
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
package code.entitlement
|
||||
|
||||
|
||||
import code.util.{MappedUUID, DefaultStringField}
|
||||
import net.liftweb.mapper._
|
||||
import net.liftweb.common.Box
|
||||
|
||||
object MappedEntitlementsProvider extends EntitlementProvider {
|
||||
|
||||
override def getEntitlement(bankId: String, userId: String, roleName: String): Box[MappedEntitlement] = {
|
||||
// Return a Box so we can handle errors later.
|
||||
MappedEntitlement.find(
|
||||
By(MappedEntitlement.mBankId, bankId),
|
||||
By(MappedEntitlement.mUserId, userId),
|
||||
By(MappedEntitlement.mRoleName, roleName)
|
||||
)
|
||||
}
|
||||
|
||||
override def getEntitlements(userId: String): Box[List[MappedEntitlement]] = {
|
||||
// Return a Box so we can handle errors later.
|
||||
Some(MappedEntitlement.findAll(
|
||||
By(MappedEntitlement.mUserId, userId),
|
||||
OrderBy(MappedEntitlement.updatedAt, Descending)))
|
||||
}
|
||||
|
||||
|
||||
override def addEntitlement(bankId: String, userId: String, roleName: String): Box[MappedEntitlement] = {
|
||||
// Return a Box so we can handle errors later.
|
||||
val addEntitlement = MappedEntitlement.create
|
||||
.mBankId(bankId)
|
||||
.mUserId(userId)
|
||||
.mRoleName(roleName)
|
||||
.saveMe()
|
||||
Some(addEntitlement)
|
||||
}
|
||||
}
|
||||
|
||||
class MappedEntitlement extends Entitlement
|
||||
with LongKeyedMapper[MappedEntitlement] with IdPK with CreatedUpdated {
|
||||
|
||||
def getSingleton = MappedEntitlement
|
||||
|
||||
object mEntitlementId extends MappedUUID(this)
|
||||
object mBankId extends DefaultStringField(this)
|
||||
object mUserId extends DefaultStringField(this)
|
||||
object mRoleName extends DefaultStringField(this)
|
||||
|
||||
override def entitlementId: String = mEntitlementId.get.toString
|
||||
override def bankId: String = mBankId.get
|
||||
override def userId: String = mUserId.get
|
||||
override def roleName: String = mRoleName.get
|
||||
|
||||
}
|
||||
|
||||
object MappedEntitlement extends MappedEntitlement with LongKeyedMetaMapper[MappedEntitlement] {
|
||||
override def dbIndexes = UniqueIndex(mEntitlementId) :: UniqueIndex(mUserId, mBankId) :: super.dbIndexes
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user