diff --git a/README.md b/README.md index e905e86cd..1b06ee0b7 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,26 @@ Please refer to the [wiki](https://github.com/OpenBankProject/OBP-API/wiki) for OBP instances support multiple versions of the API simultaniously (unless they are deactivated in config) To see the status (DRAFT, STABLE or BLEEDING-EDGE) of an API version, look at the root endpoint e.g. /obp/v2.0.0/root or /obp/v3.0.0/root +``` +24.01.2017, [V1.2.1](https://apisandbox.openbankproject.com/obp/v1.2.1/root) was marked as stable. +24.01.2017, [V1.3.0](https://apisandbox.openbankproject.com/obp/v1.3.0/root) was marked as stable. +08.06.2017, [V2.0.0](https://apisandbox.openbankproject.com/obp/v2.0.0/root) was marked as stable. +27.10.2018, [V2.1.0](https://apisandbox.openbankproject.com/obp/v2.1.0/root) was marked as stable. +27.10.2018, [V2.2.0](https://apisandbox.openbankproject.com/obp/v2.2.0/root) was marked as stable. +18.11.2020, [V3.0.0](https://apisandbox.openbankproject.com/obp/v3.0.0/root) was marked as stable. +18.11.2020, [V3.1.0](https://apisandbox.openbankproject.com/obp/v3.1.0/root) was marked as stable. +16.12.2022, [V4.0.0](https://apisandbox.openbankproject.com/obp/v4.0.0/root) was marked as stable. +16.12.2022, [V5.0.0](https://apisandbox.openbankproject.com/obp/v5.0.0/root) was marked as stable. +``` + + + + + + + + -On the 8th of June 2017, [V2.0.0](https://apisandbox.openbankproject.com/obp/v2.0.0/root) was marked as stable. ## LICENSE . diff --git a/obp-api/src/main/scala/code/api/util/ApiRole.scala b/obp-api/src/main/scala/code/api/util/ApiRole.scala index d0e64dc42..54e003512 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -323,6 +323,9 @@ object ApiRole { case class CanGetApiCollection(requiresBankId: Boolean = false) extends ApiRole lazy val canGetApiCollection = CanGetApiCollection() + case class CanGetApiCollectionsForUser(requiresBankId: Boolean = false) extends ApiRole + lazy val canGetApiCollectionsForUser = CanGetApiCollectionsForUser() + case class CanGetAllApiCollections(requiresBankId: Boolean = false) extends ApiRole lazy val canGetAllApiCollections = CanGetAllApiCollections() diff --git a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala index 52d468995..4bf14d5f3 100644 --- a/obp-api/src/main/scala/code/api/util/ErrorMessages.scala +++ b/obp-api/src/main/scala/code/api/util/ErrorMessages.scala @@ -344,7 +344,7 @@ object ErrorMessages { val ApiCollectionNotFound = "OBP-30079: ApiCollection not found." val CreateApiCollectionError = "OBP-30080: Could not create ApiCollection." - val UpdateApiCollectionError = "OBP-300801: Could not update ApiCollection." + val UpdateApiCollectionError = "OBP-3008A: Could not update ApiCollection." val DeleteApiCollectionError = "OBP-30081: Could not delete ApiCollection." val ApiCollectionEndpointNotFound = "OBP-30082: ApiCollectionEndpoint not found." diff --git a/obp-api/src/main/scala/code/api/util/NewStyle.scala b/obp-api/src/main/scala/code/api/util/NewStyle.scala index 2bb3191a3..7cca51207 100644 --- a/obp-api/src/main/scala/code/api/util/NewStyle.scala +++ b/obp-api/src/main/scala/code/api/util/NewStyle.scala @@ -3495,6 +3495,10 @@ object NewStyle extends MdcLoggable{ Future(MappedApiCollectionsProvider.getApiCollectionsByUserId(userId), callContext) } + def getAllApiCollections(callContext: Option[CallContext]) : OBPReturnType[List[ApiCollectionTrait]] = { + Future(MappedApiCollectionsProvider.getAllApiCollections(), callContext) + } + def getFeaturedApiCollections(callContext: Option[CallContext]) : OBPReturnType[List[ApiCollectionTrait]] = { //we get the getFeaturedApiCollectionIds from props, and remove the deplication there. val featuredApiCollectionIds = APIUtil.getPropsValue("featured_api_collection_ids","").split(",").map(_.trim).toSet.toList diff --git a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala index 132cb1447..e6e17dec8 100644 --- a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala +++ b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala @@ -9052,13 +9052,13 @@ trait APIMethods400 { } staticResourceDocs += ResourceDoc( - getApiCollections, + getApiCollectionsForUser, implementedInApiVersion, - nameOf(getApiCollections), + nameOf(getApiCollectionsForUser), "GET", "/users/USER_ID/api-collections", - "Get Api Collections", - s"""Get Api Collections. + "Get Api Collections for User", + s"""Get Api Collections for User. | |${authenticationRequiredMessage(true)} |""".stripMargin, @@ -9069,10 +9069,10 @@ trait APIMethods400 { UnknownError ), List(apiTagApiCollection, apiTagNewStyle), - Some(canGetAllApiCollections :: Nil) + Some(canGetApiCollectionsForUser :: Nil) ) - lazy val getApiCollections: OBPEndpoint = { + lazy val getApiCollectionsForUser: OBPEndpoint = { case "users" :: userId :: "api-collections" :: Nil JsonGet _ => { cc => for { diff --git a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala index 0641c319a..3baabaf09 100644 --- a/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala +++ b/obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala @@ -1,16 +1,15 @@ package code.api.v5_1_0 -import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{apiCollectionJson400, postApiCollectionJson400, revokedConsentJsonV310} +import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON.{apiCollectionJson400, apiCollectionsJson400, postApiCollectionJson400, revokedConsentJsonV310} import code.api.util.APIUtil._ import code.api.util.ApiRole._ -import code.api.util.ApiTag.{apiTagApiCollection, apiTagConsent, apiTagNewStyle, apiTagPSD2AIS, apiTagPsd2} -import code.api.util.ErrorMessages.{$UserNotLoggedIn, ApiCollectionAlreadyExisting, BankNotFound, ConsentNotFound, InvalidJsonFormat, UnknownError, UserNotFoundByUserId, UserNotLoggedIn} +import code.api.util.ApiTag._ +import code.api.util.ErrorMessages.{$UserNotLoggedIn, BankNotFound, ConsentNotFound, InvalidJsonFormat, UnknownError, UserNotFoundByUserId, UserNotLoggedIn, _} import code.api.util.NewStyle import code.api.util.NewStyle.HttpCode import code.api.v3_1_0.ConsentJsonV310 import code.api.v4_0_0.{JSONFactory400, PostApiCollectionJson400} -import code.apicollection.MappedApiCollectionsProvider import code.consent.Consents import code.transactionrequests.TransactionRequests.TransactionRequestTypes.{apply => _} import code.util.Helper @@ -42,7 +41,39 @@ trait APIMethods510 { val codeContext = CodeContext(staticResourceDocs, apiRelations) - resourceDocs += ResourceDoc( + staticResourceDocs += ResourceDoc( + getAllApiCollections, + implementedInApiVersion, + nameOf(getAllApiCollections), + "GET", + "/management/api-collections", + "Get All API Collections", + s"""Get All API Collections. + | + |${authenticationRequiredMessage(true)} + |""".stripMargin, + EmptyBody, + apiCollectionsJson400, + List( + UserHasMissingRoles, + UnknownError + ), + List(apiTagApiCollection, apiTagNewStyle), + Some(canGetAllApiCollections :: Nil) + ) + + lazy val getAllApiCollections: OBPEndpoint = { + case "management" :: "api-collections" :: Nil JsonGet _ => { + cc => + for { + (apiCollections, callContext) <- NewStyle.function.getAllApiCollections(cc.callContext) + } yield { + (JSONFactory400.createApiCollectionsJsonV400(apiCollections), HttpCode.`200`(callContext)) + } + } + } + + staticResourceDocs += ResourceDoc( revokeConsentAtBank, implementedInApiVersion, nameOf(revokeConsentAtBank), @@ -50,7 +81,7 @@ trait APIMethods510 { "/banks/BANK_ID/consents/CONSENT_ID/revoke", "Revoke Consent at Bank", s""" - |Revoke Consent for current user specified by CONSENT_ID + |Revoke Consent specified by CONSENT_ID | |There are a few reasons you might need to revoke an application’s access to a user’s account: | - The user explicitly wishes to revoke the application’s access diff --git a/obp-api/src/main/scala/code/apicollection/ApiCollectionsProvider.scala b/obp-api/src/main/scala/code/apicollection/ApiCollectionsProvider.scala index 1f3700570..cb691d5e3 100644 --- a/obp-api/src/main/scala/code/apicollection/ApiCollectionsProvider.scala +++ b/obp-api/src/main/scala/code/apicollection/ApiCollectionsProvider.scala @@ -25,7 +25,9 @@ trait ApiCollectionsProvider { def getApiCollectionByUserIdAndCollectionName( userId: String, apiCollectionName: String - ): Box[ApiCollectionTrait] + ): Box[ApiCollectionTrait] + + def getAllApiCollections(): List[ApiCollectionTrait] def deleteApiCollectionById( apiCollectionId: String, @@ -68,6 +70,8 @@ object MappedApiCollectionsProvider extends MdcLoggable with ApiCollectionsProvi apiCollectionId: String ) = ApiCollection.find(By(ApiCollection.ApiCollectionId,apiCollectionId)) + override def getAllApiCollections(): List[ApiCollectionTrait] = ApiCollection.findAll() + override def getApiCollectionByUserIdAndCollectionName( userId: String, apiCollectionName: String diff --git a/obp-api/src/test/resources/frozen_type_meta_data b/obp-api/src/test/resources/frozen_type_meta_data index 80ec0af9e..1d577364c 100644 Binary files a/obp-api/src/test/resources/frozen_type_meta_data and b/obp-api/src/test/resources/frozen_type_meta_data differ diff --git a/obp-api/src/test/scala/code/api/v4_0_0/ApiCollectionTest.scala b/obp-api/src/test/scala/code/api/v4_0_0/ApiCollectionTest.scala index 9f0ee9487..c621658d2 100644 --- a/obp-api/src/test/scala/code/api/v4_0_0/ApiCollectionTest.scala +++ b/obp-api/src/test/scala/code/api/v4_0_0/ApiCollectionTest.scala @@ -53,7 +53,7 @@ class ApiCollectionTest extends V400ServerSetup { object ApiEndpoint7 extends Tag(nameOf(Implementations4_0_0.getMyApiCollectionById)) object ApiEndpoint5 extends Tag(nameOf(Implementations4_0_0.getSharableApiCollectionById)) - object ApiEndpoint6 extends Tag(nameOf(Implementations4_0_0.getApiCollections)) + object ApiEndpoint6 extends Tag(nameOf(Implementations4_0_0.getApiCollectionsForUser)) feature("Test the apiCollection endpoints") { scenario("We create my apiCollection and get,delete", ApiEndpoint1,ApiEndpoint2, ApiEndpoint3, ApiEndpoint4, ApiEndpoint7, VersionOfApi) { @@ -232,7 +232,7 @@ class ApiCollectionTest extends V400ServerSetup { responseApiEndpoint6.body.toString contains(s"$UserHasMissingRoles") should be (true) Then("grant the role and test it again") - Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.canGetAllApiCollections.toString) + Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.canGetApiCollectionsForUser.toString) val responseApiEndpoint6WithRole = makeGetRequest(requestApiEndpoint6) Then("We should get a 200") diff --git a/obp-api/src/test/scala/code/api/v5_1_0/ApiCollectionTest.scala b/obp-api/src/test/scala/code/api/v5_1_0/ApiCollectionTest.scala index 6d57f9b37..39bcf600f 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/ApiCollectionTest.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/ApiCollectionTest.scala @@ -27,10 +27,12 @@ package code.api.v5_1_0 import code.api.ResourceDocs1_4_0.SwaggerDefinitionsJSON import code.api.util.APIUtil.OAuth._ -import code.api.util.ErrorMessages.UserNotLoggedIn +import code.api.util.ApiRole +import code.api.util.ErrorMessages.{UserHasMissingRoles, UserNotLoggedIn} import code.api.v4_0_0.APIMethods400.Implementations4_0_0 -import code.api.v4_0_0.ApiCollectionJson400 -import code.api.v5_1_0.APIMethods510.Implementations5_1_0 +import code.api.v4_0_0.{ApiCollectionJson400, ApiCollectionsJson400} +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.ErrorMessage import com.openbankproject.commons.util.ApiVersion @@ -50,7 +52,54 @@ class ApiCollectionTest extends V510ServerSetup { object ApiEndpoint1 extends Tag(nameOf(Implementations4_0_0.createMyApiCollection)) object ApiEndpoint2 extends Tag(nameOf(Implementations4_0_0.getMyApiCollectionById)) object ApiEndpoint3 extends Tag(nameOf(Implementations5_1_0.updateMyApiCollection)) + object ApiEndpoint8 extends Tag(nameOf(Implementations5_1_0.getAllApiCollections)) + feature("Test the apiCollection endpoints") { + scenario("We create the apiCollection get All API collections back", ApiEndpoint8, VersionOfApi) { + When("We make a request v4.0.0") + + val request = (v5_1_0_Request / "my" / "api-collections").POST <@ (user1) + + lazy val postApiCollectionJson = SwaggerDefinitionsJSON.postApiCollectionJson400 + val response = makePostRequest(request, write(postApiCollectionJson)) + Then("We should get a 201") + response.code should equal(201) + val apiCollectionJson400 = response.body.extract[ApiCollectionJson400] + + + val requestUser2 = (v5_1_0_Request / "my" / "api-collections").POST <@ (user2) + val responseUser2 = makePostRequest(requestUser2, write(postApiCollectionJson)) + Then("We should get a 201") + responseUser2.code should equal(201) + + Then(s"we test the $ApiEndpoint8") + val requestApiEndpoint = (v5_1_0_Request / "management" / "api-collections").GET + val requestApiEndpoint8 = (v5_1_0_Request /"management" / "api-collections").GET <@ (user1) + + val responseApiEndpoint8 = makeGetRequest(requestApiEndpoint) + Then(s"we should get the error messages") + responseApiEndpoint8.code should equal(401) + responseApiEndpoint8.body.toString contains(s"$UserNotLoggedIn") should be (true) + + { + Then(s"we test the $ApiEndpoint8") + val responseApiEndpoint8 = makeGetRequest(requestApiEndpoint8) + Then(s"we should get the error messages") + responseApiEndpoint8.code should equal(403) + responseApiEndpoint8.body.toString contains(s"$UserHasMissingRoles") should be (true) + } + Then("grant the role and test it again") + Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, ApiRole.canGetAllApiCollections.toString) + val responseApiEndpoint8WithRole = makeGetRequest(requestApiEndpoint8) + + Then("We should get a 200") + responseApiEndpoint8WithRole.code should equal(200) + val apiCollectionsResponseApiEndpoint8 = responseApiEndpoint8WithRole.body.extract[ApiCollectionsJson400] + apiCollectionsResponseApiEndpoint8.api_collections.head should be (apiCollectionJson400) + + } + } + feature(s"test $ApiEndpoint1 version $VersionOfApi - Unauthorized access") { scenario("We will call the endpoint without user credentials", ApiEndpoint1, VersionOfApi) { When(s"We make a request $ApiEndpoint1") diff --git a/obp-api/src/test/scala/code/api/v5_1_0/V510ServerSetup.scala b/obp-api/src/test/scala/code/api/v5_1_0/V510ServerSetup.scala index ec228c3e9..bf9edddfc 100644 --- a/obp-api/src/test/scala/code/api/v5_1_0/V510ServerSetup.scala +++ b/obp-api/src/test/scala/code/api/v5_1_0/V510ServerSetup.scala @@ -11,6 +11,8 @@ import scala.util.Random.nextInt trait V510ServerSetup extends ServerSetupWithTestData with DefaultUsers { + def v4_0_0_Request: Req = baseRequest / "obp" / "v4.0.0" + def v5_0_0_Request: Req = baseRequest / "obp" / "v5.0.0" def v5_1_0_Request: Req = baseRequest / "obp" / "v5.1.0" def dynamicEndpoint_Request: Req = baseRequest / "obp" / ApiShortVersions.`dynamic-endpoint`.toString def dynamicEntity_Request: Req = baseRequest / "obp" / ApiShortVersions.`dynamic-entity`.toString diff --git a/pom.xml b/pom.xml index 1606ba75e..efb6ae00c 100644 --- a/pom.xml +++ b/pom.xml @@ -271,6 +271,14 @@ false + + + + org.apache.maven.plugins + maven-site-plugin + 3.7.1 + +