mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 17:17:09 +00:00
feature/OBPv510 added deleteUserAttribute endpoint
This commit is contained in:
parent
f77e9f41a5
commit
1a4eefaf9d
@ -406,6 +406,9 @@ object ApiRole {
|
||||
|
||||
case class CanCreateUserAttribute (requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canCreateUserAttribute = CanCreateUserAttribute()
|
||||
|
||||
case class CanDeleteUserAttribute (requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canDeleteUserAttribute = CanDeleteUserAttribute()
|
||||
|
||||
case class CanReadUserLockedStatus(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canReadUserLockedStatus = CanReadUserLockedStatus()
|
||||
|
||||
@ -15,6 +15,7 @@ import code.api.v3_1_0.ConsentJsonV310
|
||||
import code.api.v3_1_0.JSONFactory310.createBadLoginStatusJson
|
||||
import code.api.v4_0_0.{JSONFactory400, PostApiCollectionJson400, UserAttributeJsonV400}
|
||||
import code.atmattribute.AtmAttribute
|
||||
import code.bankconnectors.Connector
|
||||
import code.consent.Consents
|
||||
import code.loginattempts.LoginAttempt
|
||||
import code.metrics.APIMetrics
|
||||
@ -132,6 +133,7 @@ trait APIMethods510 {
|
||||
userAttributeResponseJson,
|
||||
List(
|
||||
$UserNotLoggedIn,
|
||||
UserHasMissingRoles,
|
||||
InvalidJsonFormat,
|
||||
UnknownError
|
||||
),
|
||||
@ -144,7 +146,7 @@ trait APIMethods510 {
|
||||
cc =>
|
||||
val failMsg = s"$InvalidJsonFormat The Json body should be the $UserAttributeJsonV400 "
|
||||
for {
|
||||
(attributes, callContext) <- NewStyle.function.getUserAttributes(userId, cc.callContext)
|
||||
(user, callContext) <- NewStyle.function.getUserByUserId(userId, cc.callContext)
|
||||
postedData <- NewStyle.function.tryons(failMsg, 400, callContext) {
|
||||
json.extract[UserAttributeJsonV400]
|
||||
}
|
||||
@ -154,7 +156,7 @@ trait APIMethods510 {
|
||||
UserAttributeType.withName(postedData.`type`)
|
||||
}
|
||||
(userAttribute, callContext) <- NewStyle.function.createOrUpdateUserAttribute(
|
||||
userId,
|
||||
user.userId,
|
||||
None,
|
||||
postedData.name,
|
||||
userAttributeType,
|
||||
@ -165,7 +167,48 @@ trait APIMethods510 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resourceDocs += ResourceDoc(
|
||||
deleteUserAttribute,
|
||||
implementedInApiVersion,
|
||||
nameOf(deleteUserAttribute),
|
||||
"DELETE",
|
||||
"/users/USER_ID/attributes/USER_ATTRIBUTE_ID",
|
||||
"Delete User Attribute",
|
||||
s"""Delete the User Attribute specified by ENTITLEMENT_REQUEST_ID for a user specified by USER_ID
|
||||
|
|
||||
|${authenticationRequiredMessage(true)}
|
||||
|""".stripMargin,
|
||||
EmptyBody,
|
||||
EmptyBody,
|
||||
List(
|
||||
UserNotLoggedIn,
|
||||
UserHasMissingRoles,
|
||||
InvalidConnectorResponse,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagUser, apiTagNewStyle),
|
||||
Some(List(canDeleteUserAttribute)))
|
||||
|
||||
lazy val deleteUserAttribute: OBPEndpoint = {
|
||||
case "users" :: userId :: "attributes" :: userAttributeId :: Nil JsonDelete _ => {
|
||||
cc =>
|
||||
for {
|
||||
(_, callContext) <- authenticatedAccess(cc)
|
||||
(_, callContext) <- NewStyle.function.getUserByUserId(userId, callContext)
|
||||
(deleted,callContext) <- Connector.connector.vend.deleteUserAttribute(
|
||||
userAttributeId: String,
|
||||
callContext: Option[CallContext]
|
||||
) map {
|
||||
i => (connectorEmptyResponse (i._1, callContext), i._2)
|
||||
}
|
||||
} yield {
|
||||
(Full(deleted), HttpCode.`204`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
customViewNamesCheck,
|
||||
implementedInApiVersion,
|
||||
|
||||
@ -2272,6 +2272,11 @@ trait Connector extends MdcLoggable {
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Box[UserAttribute]] = Future{(Failure(setUnimplementedError), callContext)}
|
||||
|
||||
def deleteUserAttribute(
|
||||
userAttributeId: String,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Box[Boolean]] = Future{(Failure(setUnimplementedError), callContext)}
|
||||
|
||||
def createOrUpdateTransactionAttribute(
|
||||
bankId: BankId,
|
||||
transactionId: TransactionId,
|
||||
|
||||
@ -4080,6 +4080,9 @@ object LocalMappedConnector extends Connector with MdcLoggable {
|
||||
override def getUserAttributesByUsers(userIds: List[String], callContext: Option[CallContext]): OBPReturnType[Box[List[UserAttribute]]] = {
|
||||
UserAttributeProvider.userAttributeProvider.vend.getUserAttributesByUsers(userIds) map {(_, callContext)}
|
||||
}
|
||||
override def deleteUserAttribute(userAttributeId: String, callContext: Option[CallContext]): OBPReturnType[Box[Boolean]] = {
|
||||
UserAttributeProvider.userAttributeProvider.vend.deleteUserAttribute(userAttributeId) map {(_, callContext)}
|
||||
}
|
||||
override def createOrUpdateUserAttribute(
|
||||
userId: String,
|
||||
userAttributeId: Option[String],
|
||||
|
||||
@ -22,6 +22,9 @@ object RemotedataUserAttribute extends ObpActorInit with UserAttributeProvider {
|
||||
override def getUserAttributesByUsers(userIds: List[String]): Future[Box[List[UserAttribute]]] =
|
||||
(actor ? cc.getUserAttributesByUsers(userIds)).mapTo[Box[List[UserAttribute]]]
|
||||
|
||||
override def deleteUserAttribute(userAttributeId: String): Future[Box[Boolean]] =
|
||||
(actor ? cc.deleteUserAttribute(userAttributeId: String)).mapTo[Box[Boolean]]
|
||||
|
||||
override def createOrUpdateUserAttribute(userId: String,
|
||||
userAttributeId: Option[String],
|
||||
name: String,
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
package code.users
|
||||
|
||||
import java.util.Date
|
||||
import code.api.util.ErrorMessages
|
||||
|
||||
import java.util.Date
|
||||
import code.util.MappedUUID
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.UserAttributeTrait
|
||||
@ -25,6 +26,16 @@ object MappedUserAttributeProvider extends UserAttributeProvider {
|
||||
UserAttribute.findAll(ByList(UserAttribute.UserId, userIds))
|
||||
)
|
||||
}
|
||||
|
||||
override def deleteUserAttribute(userAttributeId: String): Future[Box[Boolean]] = {
|
||||
Future {
|
||||
UserAttribute.find(By(UserAttribute.UserAttributeId, userAttributeId)) match {
|
||||
case Full(t) => Full(t.delete_!)
|
||||
case Empty => Empty ?~! ErrorMessages.UserAttributeNotFound
|
||||
case _ => Full(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def createOrUpdateUserAttribute(userId: String,
|
||||
userAttributeId: Option[String],
|
||||
|
||||
@ -39,6 +39,7 @@ trait UserAttributeProvider {
|
||||
|
||||
def getUserAttributesByUser(userId: String): Future[Box[List[UserAttribute]]]
|
||||
def getUserAttributesByUsers(userIds: List[String]): Future[Box[List[UserAttribute]]]
|
||||
def deleteUserAttribute(userAttributeId: String): Future[Box[Boolean]]
|
||||
def createOrUpdateUserAttribute(userId: String,
|
||||
userAttributeId: Option[String],
|
||||
name: String,
|
||||
@ -49,6 +50,7 @@ trait UserAttributeProvider {
|
||||
|
||||
class RemotedataUserAttributeCaseClasses {
|
||||
case class getUserAttributesByUser(userId: String)
|
||||
case class deleteUserAttribute(userAttributeId: String)
|
||||
case class getUserAttributesByUsers(userIds: List[String])
|
||||
case class createOrUpdateUserAttribute(userId: String,
|
||||
userAttributeId: Option[String],
|
||||
|
||||
@ -11,7 +11,6 @@ import code.entitlement.Entitlement
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import com.openbankproject.commons.model.ErrorMessage
|
||||
import com.openbankproject.commons.util.ApiVersion
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.json.Serialization.write
|
||||
import org.scalatest.Tag
|
||||
|
||||
@ -26,6 +25,7 @@ class UserAttributesTest extends V510ServerSetup {
|
||||
*/
|
||||
object VersionOfApi extends Tag(ApiVersion.v5_1_0.toString)
|
||||
object ApiEndpoint1 extends Tag(nameOf(Implementations5_1_0.createUserAttribute))
|
||||
object ApiEndpoint2 extends Tag(nameOf(Implementations5_1_0.deleteUserAttribute))
|
||||
|
||||
|
||||
lazy val bankId = testBankId1.value
|
||||
@ -36,24 +36,32 @@ class UserAttributesTest extends V510ServerSetup {
|
||||
|
||||
|
||||
|
||||
feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") {
|
||||
scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
feature(s"test $ApiEndpoint1 $ApiEndpoint2 version $VersionOfApi - Unauthorized access") {
|
||||
scenario(s"We will call the end $ApiEndpoint1 without user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v5.1.0")
|
||||
val request510 = (v5_1_0_Request / "users" /"testuserId"/ "attributes").POST
|
||||
val request510 = (v5_1_0_Request / "users" /"testUserId"/ "attributes").POST
|
||||
val response510 = makePostRequest(request510, write(postUserAttributeJsonV510))
|
||||
Then("We should get a 401")
|
||||
response510.code should equal(401)
|
||||
response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
|
||||
scenario(s"We will call the $ApiEndpoint2 without user credentials", ApiEndpoint1, VersionOfApi) {
|
||||
When("We make a request v5.1.0")
|
||||
val request510 = (v5_1_0_Request / "users" /"testUserId"/ "attributes"/"testUserAttributeId").POST
|
||||
val response510 = makeDeleteRequest(request510)
|
||||
Then("We should get a 401")
|
||||
response510.code should equal(401)
|
||||
response510.body.extract[ErrorMessage].message should equal(UserNotLoggedIn)
|
||||
}
|
||||
}
|
||||
|
||||
feature(s"test $ApiEndpoint1 version $VersionOfApi - authorized access") {
|
||||
scenario("We will call the endpoint with user credentials, but missing role", ApiEndpoint1, VersionOfApi) {
|
||||
feature(s"test $ApiEndpoint1 $ApiEndpoint2 version $VersionOfApi - authorized access") {
|
||||
scenario(s"We will call the $ApiEndpoint1 $ApiEndpoint2 with user credentials", ApiEndpoint1, ApiEndpoint2,VersionOfApi) {
|
||||
When("We make a request v5.1.0, we need to prepare the roles and users")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanGetAnyUser.toString)
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanCreateUserAttribute.toString)
|
||||
|
||||
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanDeleteUserAttribute.toString)
|
||||
|
||||
val requestGetUsers = (v5_1_0_Request / "users").GET <@ (user1)
|
||||
val responseGetUsers = makeGetRequest(requestGetUsers)
|
||||
@ -65,10 +73,23 @@ class UserAttributesTest extends V510ServerSetup {
|
||||
Then("We should get a 201")
|
||||
response510.code should equal(201)
|
||||
val jsonResponse = response510.body.extract[UserAttributeResponseJsonV400]
|
||||
jsonResponse.name should be(batteryLevel)
|
||||
val userAttributeId = jsonResponse.user_attribute_id
|
||||
|
||||
|
||||
val requestDeleteUserAttribute = (v5_1_0_Request / "users"/ userId/"attributes"/userAttributeId).DELETE <@ (user1)
|
||||
val responseDeleteUserAttribute = makeDeleteRequest(requestDeleteUserAttribute)
|
||||
Then("We should get a 204")
|
||||
responseDeleteUserAttribute.code should equal(204)
|
||||
|
||||
Then("We delete it again, we should get the can not find error")
|
||||
val responseDeleteUserAttributeAgain = makeDeleteRequest(requestDeleteUserAttribute)
|
||||
Then("We should get a 400")
|
||||
responseDeleteUserAttributeAgain.code should equal(400)
|
||||
responseDeleteUserAttributeAgain.body.extract[ErrorMessage].message contains (UserAttributeNotFound) shouldBe( true)
|
||||
|
||||
}
|
||||
|
||||
scenario("We will call the endpoint with user credentials, but missing roles", ApiEndpoint1, VersionOfApi) {
|
||||
scenario(s"We will call the $ApiEndpoint1 with user credentials, but missing roles", ApiEndpoint1, ApiEndpoint2, VersionOfApi) {
|
||||
When("We make a request v5.1.0, we need to prepare the roles and users")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanGetAnyUser.toString)
|
||||
|
||||
@ -84,6 +105,23 @@ class UserAttributesTest extends V510ServerSetup {
|
||||
response510.body.extract[ErrorMessage].message contains (UserHasMissingRoles) shouldBe (true)
|
||||
response510.body.extract[ErrorMessage].message contains (ApiRole.CanCreateUserAttribute.toString()) shouldBe (true)
|
||||
}
|
||||
|
||||
scenario(s"We will call the $ApiEndpoint2 with user credentials, but missing roles", ApiEndpoint1, ApiEndpoint2, VersionOfApi) {
|
||||
When("We make a request v5.1.0, we need to prepare the roles and users")
|
||||
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.CanGetAnyUser.toString)
|
||||
|
||||
val requestGetUsers = (v5_1_0_Request / "users").GET <@ (user1)
|
||||
val responseGetUsers = makeGetRequest(requestGetUsers)
|
||||
val userIds = responseGetUsers.body.extract[UsersJsonV400].users.map(_.user_id)
|
||||
val userId = userIds(scala.util.Random.nextInt(userIds.size))
|
||||
|
||||
val request510 = (v5_1_0_Request / "users" / userId / "attributes" / "attributeId").DELETE <@ (user1)
|
||||
val response510 = makeDeleteRequest(request510)
|
||||
Then("We should get a 403")
|
||||
response510.code should equal(403)
|
||||
response510.body.extract[ErrorMessage].message contains (UserHasMissingRoles) shouldBe (true)
|
||||
response510.body.extract[ErrorMessage].message contains (ApiRole.CanDeleteUserAttribute.toString()) shouldBe (true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user