diff --git a/src/main/scala/code/bankconnectors/Connector.scala b/src/main/scala/code/bankconnectors/Connector.scala index 55c0815aa..3816b3423 100644 --- a/src/main/scala/code/bankconnectors/Connector.scala +++ b/src/main/scala/code/bankconnectors/Connector.scala @@ -1228,6 +1228,9 @@ trait Connector extends MdcLoggable{ } + //This method is in Connector.scala, not in MappedView.scala. + //Reason: this method is only used for different connectors. Used for mapping users/accounts/ between MainFrame and OBP. + // Not used for creating views from OBP-API side. def createViews(bankId: BankId, accountId: AccountId, owner_view: Boolean = false, public_view: Boolean = false, accountants_view: Boolean = false, diff --git a/src/main/scala/code/model/View.scala b/src/main/scala/code/model/View.scala index f046ef19a..6438cb35e 100644 --- a/src/main/scala/code/model/View.scala +++ b/src/main/scala/code/model/View.scala @@ -196,19 +196,28 @@ case class UpdateViewJSON( trait View { val viewLogger = Logger(classOf[View]) - //e.g. "Public", "Authorities", "Our Network", etc. + // metedataView is tricky, it used for all the transaction meta in different views share the same metadataView. + // we create, get, update transaction.meta call the deufault metadataView. Not the currentView. + // eg: If current view is _tesobe, you set metadataView is `owner`, then all the transaction.meta will just point to `owner` view. + // Look into the following method in code, you will know more about it: + // code.metadata.wheretags.MapperWhereTags.addWhereTag + // val metadateViewId = Views.views.vend.getMetadataViewId(BankIdAccountId(bankId, accountId), viewId) + def metadataView : String + //This is used for distinguishing all the views //For now, we need have some system views and user created views. - // System Views: eg: owner, accountant ... They are the fixed views, account owner can not modify it. - // User Created Views: Start with _, eg _son, _wife ... The owner can update the fields for these views. - def metadataView : String + // 1 `System Views` : eg: owner, accountant ... They are the fixed views, developers can not modify it. + // 2 `User Created Views`: Start with _, eg _son, _wife ... The developers can update the fields for these views. def isSystem : Boolean def isFirehose : Boolean def isPublic : Boolean def isPrivate : Boolean - //these ids are used together to uniquely identify a view + //these three Ids are used together to uniquely identify a view: + // eg: a view = viewId(`owner`) + accountId('e4f001fe-0f0d-4f93-a8b2-d865077315ec')+bankId('gh.29.uk') + // the viewId is not OBP uuid here, view.viewId is view.name without spaces and lowerCase. (view.name = my life) <---> (view-permalink = mylife) + // aslo @code.views.MapperViews.createView see how we create the viewId. def viewId : ViewId def accountId : AccountId def bankId : BankId @@ -216,8 +225,27 @@ trait View { //and here is the unique identifier def uid : ViewIdBankIdAccountId = ViewIdBankIdAccountId(viewId, bankId, accountId) + //The name is the orignal value from developer, when they create the views. + // It can be any string value, also see the viewId, + // the viewId is not OBP uuid here, view.viewId is view.name without spaces and lowerCase. (view.name = my life) <---> (view-permalink = mylife) + // aslo @code.views.MapperViews.createView see how we create the viewId. def name: String + //the Value from developer, can be any string value. def description : String + + /**This users is tricky, this use ManyToMany relationship, + 1st: when create view, we need carefully map this view to the owner user. + 2rd: the view can grant the access to any other (not owner) users. eg: Simon's accountant view can grant access to Carola, then Carola can see Simon's accountant data + also look into some createView methods in code, you can understand more: + create1: code.bankconnectors.Connector.createViews + need also look into here code.bankconnectors.vMar2017.KafkaMappedConnector_vMar2017.updateUserAccountViewsOld + after createViews method, always need call addPermission(v.uid, user). This will create this field + Create2: code.model.dataAccess.BankAccountCreation.createOwnerView + after create view, always need call `addPermission(ownerViewUID, user)`, this will create this field + create3: code.model.dataAccess.AuthUser#updateUserAccountViews + after create view, always need call `getOrCreateViewPrivilege(view,user)`, this will create this filed + Both uses should be in this List. + */ def users: List[User] //the view settings diff --git a/src/main/scala/code/model/dataAccess/AuthUser.scala b/src/main/scala/code/model/dataAccess/AuthUser.scala index a0687d8dc..70159b8f2 100644 --- a/src/main/scala/code/model/dataAccess/AuthUser.scala +++ b/src/main/scala/code/model/dataAccess/AuthUser.scala @@ -861,7 +861,7 @@ import net.liftweb.util.Helpers._ bankAccountUID <- Full(BankIdAccountId(BankId(account.bankId), AccountId(account.accountId))) view <- Views.views.vend.getOrCreateAccountView(bankAccountUID, viewId) } yield { - Views.views.vend.getOrCreateViewPrivilege(view,user) + Views.views.vend.addPermission(view.uid, user) AccountHolders.accountHolders.vend.getOrCreateAccountHolder(user,bankAccountUID) } } diff --git a/src/main/scala/code/model/dataAccess/MappedView.scala b/src/main/scala/code/model/dataAccess/MappedView.scala index 92b38ec03..23c2e1c0e 100644 --- a/src/main/scala/code/model/dataAccess/MappedView.scala +++ b/src/main/scala/code/model/dataAccess/MappedView.scala @@ -58,6 +58,8 @@ class ViewImpl extends View with LongKeyedMapper[ViewImpl] with ManyToMany with def getSingleton = ViewImpl def primaryKeyField = id_ + + //This field used ManyToMany object users_ extends MappedManyToMany(ViewPrivileges, ViewPrivileges.view, ViewPrivileges.user, ResourceUser) object bankPermalink extends UUIDString(this) diff --git a/src/main/scala/code/remotedata/RemotedataViews.scala b/src/main/scala/code/remotedata/RemotedataViews.scala index c5b7c0733..aeadc3b7c 100644 --- a/src/main/scala/code/remotedata/RemotedataViews.scala +++ b/src/main/scala/code/remotedata/RemotedataViews.scala @@ -22,9 +22,6 @@ object RemotedataViews extends ObpActorInit with Views { def addPermission(viewIdBankIdAccountId: ViewIdBankIdAccountId, user: User): Box[View] = extractFutureToBox(actor ? cc.addPermission(viewIdBankIdAccountId, user)) - def getOrCreateViewPrivilege(view: View, user: User): Box[View] = - extractFutureToBox(actor ? cc.getOrCreateViewPrivilege(view: View, user: User)) - def revokePermission(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[Boolean] = extractFutureToBox(actor ? cc.revokePermission(viewIdBankIdAccountId, user)) diff --git a/src/main/scala/code/remotedata/RemotedataViewsActor.scala b/src/main/scala/code/remotedata/RemotedataViewsActor.scala index 0aab5e159..d5ef8ff1a 100644 --- a/src/main/scala/code/remotedata/RemotedataViewsActor.scala +++ b/src/main/scala/code/remotedata/RemotedataViewsActor.scala @@ -22,11 +22,6 @@ class RemotedataViewsActor extends Actor with ObpActorHelper with MdcLoggable { logger.debug("addPermission(" + viewIdBankIdAccountId +"," + user +")") sender ! extractResult(mapper.addPermission(viewIdBankIdAccountId, user)) - // TODO Remove duplicate bankId accountId inputs here. - case cc.getOrCreateViewPrivilege(view: View, user: User) => - logger.debug("getOrCreateViewPrivilege(" + view +"," + user +")") - sender ! extractResult(mapper.getOrCreateViewPrivilege(view: View, user: User)) - case cc.permission(account : BankIdAccountId, user: User) => logger.debug("permission(" + account +"," + user +")") sender ! extractResult(mapper.permission(account, user)) diff --git a/src/main/scala/code/views/MapperViews.scala b/src/main/scala/code/views/MapperViews.scala index cdc24d851..eb9729259 100644 --- a/src/main/scala/code/views/MapperViews.scala +++ b/src/main/scala/code/views/MapperViews.scala @@ -62,20 +62,6 @@ object MapperViews extends Views with MdcLoggable { Full(Permission(user, views)) } - /** - * This gives the user access to the view. - * Note: This method is a little different with addPermission, - * The parameter is the view object, and this view can be changed to ViewImpl - */ - def getOrCreateViewPrivilege(view: View, user: User): Box[View] = { - - val viewImpl = view.asInstanceOf[ViewImpl] - - if(viewImpl.isPublic && !ALLOW_PUBLIC_VIEWS) return Failure(PublicViewsNotAllowedOnThisInstance) - // SQL Select Count ViewPrivileges where - getOrCreateViewPrivilege(user, viewImpl) - } - private def getOrCreateViewPrivilege(user: User, viewImpl: ViewImpl): Box[ViewImpl] = { if (ViewPrivileges.count(By(ViewPrivileges.user, user.resourceUserId.value), By(ViewPrivileges.view, viewImpl.id)) == 0) { //logger.debug(s"saving ViewPrivileges for user ${user.resourceUserId.value} for view ${vImpl.id}") @@ -225,7 +211,7 @@ object MapperViews extends Views with MdcLoggable { if(view.name.contentEquals("")) { return Failure("You cannot create a View with an empty Name") } - //view-permalink is view.name without spaces. (view.name = my life) <---> (view-permalink = mylife) + //view-permalink is view.name without spaces and lowerCase. (view.name = my life) <---> (view-permalink = mylife) val newViewPermalink = { view.name.replaceAllLiterally(" ", "").toLowerCase } diff --git a/src/main/scala/code/views/Views.scala b/src/main/scala/code/views/Views.scala index caf0ac5c6..10529d4d3 100644 --- a/src/main/scala/code/views/Views.scala +++ b/src/main/scala/code/views/Views.scala @@ -32,9 +32,11 @@ trait Views { def permissions(account : BankIdAccountId) : List[Permission] def permission(account : BankIdAccountId, user: User) : Box[Permission] - def getOrCreateViewPrivilege(view: View, user: User): Box[View] - // This is for ViewPrivileges. It will first find the view object by `viewIdBankIdAccountId` - // And than, @getOrCreateViewPrivilege(view: View, user: User) for the view and user. + /** + * This is for @ViewPrivileges. + * It will first find the view object by `viewIdBankIdAccountId` + * And then, call @getOrCreateViewPrivilege(view: View, user: User) for the view and user. + */ def addPermission(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[View] def addPermissions(views : List[ViewIdBankIdAccountId], user : User) : Box[List[View]] def revokePermission(viewIdBankIdAccountId : ViewIdBankIdAccountId, user : User) : Box[Boolean] diff --git a/src/test/scala/code/views/MappedViewsTest.scala b/src/test/scala/code/views/MappedViewsTest.scala index 947d95a39..ca72296ee 100644 --- a/src/test/scala/code/views/MappedViewsTest.scala +++ b/src/test/scala/code/views/MappedViewsTest.scala @@ -69,33 +69,7 @@ class MappedViewsTest extends ServerSetup with DefaultUsers{ } - scenario("test - getOrCreateViewPrivilege") { - - Given("the view and user for this method") - val viewOwner = MapperViews.getOrCreateAccountView(bankIdAccountId, viewIdOwner).head - viewOwner.viewId.value should equal("Owner".toLowerCase()) - - Then("call the method, create the Privilege") - MapperViews.getOrCreateViewPrivilege(viewOwner, resourceUser1) - - Then("Check the result.") - val viewImpl = viewOwner.asInstanceOf[ViewImpl] - val numberOfViewPrivilege= ViewPrivileges.count( - By(ViewPrivileges.user, resourceUser1.resourceUserId.value), - By(ViewPrivileges.view, viewImpl.id) - ) - numberOfViewPrivilege should be(1) - - Then("call the method again") - MapperViews.getOrCreateViewPrivilege(viewOwner, resourceUser1) - - Then("We check the result, the number should be the same") - val numberOfViewPrivilege2= ViewPrivileges.count( - By(ViewPrivileges.user, resourceUser1.resourceUserId.value), - By(ViewPrivileges.view, viewImpl.id) - ) - numberOfViewPrivilege2 should be(1) - } + }