mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 11:06:49 +00:00
Feature: Featured API collections endpoints
This commit is contained in:
parent
7cec58749c
commit
5d353c80f6
@ -49,6 +49,7 @@ import code.api.util._
|
||||
import code.api.util.migration.Migration
|
||||
import code.api.util.migration.Migration.DbFunction
|
||||
import code.apicollection.ApiCollection
|
||||
import code.featuredapicollection.FeaturedApiCollection
|
||||
import code.apicollectionendpoint.ApiCollectionEndpoint
|
||||
import code.atmattribute.AtmAttribute
|
||||
import code.atms.MappedAtm
|
||||
@ -1118,6 +1119,7 @@ object ToSchemify {
|
||||
MappedUserRefreshes,
|
||||
ApiCollection,
|
||||
ApiCollectionEndpoint,
|
||||
FeaturedApiCollection,
|
||||
JsonSchemaValidation,
|
||||
AuthenticationTypeValidation,
|
||||
ConnectorMethod,
|
||||
|
||||
@ -5175,6 +5175,12 @@ object SwaggerDefinitionsJSON {
|
||||
lazy val apiCollectionEndpointJson400 = ApiCollectionEndpointJson400(apiCollectionEndpointIdExample.value, apiCollectionIdExample.value, operationIdExample.value)
|
||||
lazy val apiCollectionEndpointsJson400 = ApiCollectionEndpointsJson400(List(apiCollectionEndpointJson400))
|
||||
|
||||
// Featured API Collections (v6.0.0)
|
||||
lazy val postFeaturedApiCollectionJsonV600 = PostFeaturedApiCollectionJsonV600(apiCollectionIdExample.value, 1)
|
||||
lazy val putFeaturedApiCollectionJsonV600 = PutFeaturedApiCollectionJsonV600(1)
|
||||
lazy val featuredApiCollectionJsonV600 = FeaturedApiCollectionJsonV600(featuredApiCollectionIdExample.value, apiCollectionIdExample.value, 1)
|
||||
lazy val featuredApiCollectionsJsonV600 = FeaturedApiCollectionsJsonV600(List(featuredApiCollectionJsonV600))
|
||||
|
||||
lazy val jsonScalaConnectorMethod = JsonConnectorMethod(Some(connectorMethodIdExample.value),"getBank", connectorMethodBodyScalaExample.value, "Scala")
|
||||
lazy val jsonScalaConnectorMethodMethodBody = JsonConnectorMethodMethodBody(connectorMethodBodyScalaExample.value, "Scala")
|
||||
|
||||
|
||||
@ -377,7 +377,10 @@ object ApiRole extends MdcLoggable{
|
||||
|
||||
case class CanGetAllApiCollections(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canGetAllApiCollections = CanGetAllApiCollections()
|
||||
|
||||
|
||||
case class CanManageFeaturedApiCollections(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canManageFeaturedApiCollections = CanManageFeaturedApiCollections()
|
||||
|
||||
case class CanGetCounterpartyAtAnyBank(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canGetCounterpartyAtAnyBank = CanGetCounterpartyAtAnyBank()
|
||||
|
||||
|
||||
@ -436,6 +436,12 @@ object ErrorMessages {
|
||||
val ApiCollectionEndpointAlreadyExists = "OBP-30085: The ApiCollectionEndpoint is already exists."
|
||||
val ApiCollectionAlreadyExists = "OBP-30086: The ApiCollection is already exists."
|
||||
|
||||
val FeaturedApiCollectionNotFound = "OBP-30400: FeaturedApiCollection not found. Please specify a valid value for API_COLLECTION_ID."
|
||||
val CreateFeaturedApiCollectionError = "OBP-30401: Could not create FeaturedApiCollection."
|
||||
val UpdateFeaturedApiCollectionError = "OBP-30402: Could not update FeaturedApiCollection."
|
||||
val DeleteFeaturedApiCollectionError = "OBP-30403: Could not delete FeaturedApiCollection."
|
||||
val FeaturedApiCollectionAlreadyExists = "OBP-30404: The ApiCollection is already featured."
|
||||
|
||||
val DoubleEntryTransactionNotFound = "OBP-30087: Double Entry Transaction not found."
|
||||
|
||||
val InvalidAuthContextUpdateRequestKey = "OBP-30088: Invalid Auth Context Update Request Key."
|
||||
|
||||
@ -285,7 +285,13 @@ object ExampleValue {
|
||||
|
||||
lazy val apiCollectionEndpointIdExample = ConnectorField("8uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", "A string that MUST uniquely identify the session on this OBP instance, can be used in all cache.")
|
||||
glossaryItems += makeGlossaryItem("ApiCollectionEndpoint.apiCollectionEndpointId", apiCollectionEndpointIdExample)
|
||||
|
||||
|
||||
lazy val featuredApiCollectionIdExample = ConnectorField("9uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", "A string that uniquely identifies this featured API collection entry.")
|
||||
glossaryItems += makeGlossaryItem("FeaturedApiCollection.featuredApiCollectionId", featuredApiCollectionIdExample)
|
||||
|
||||
lazy val sortOrderExample = ConnectorField("1", "The sort order for displaying featured API collections. Lower numbers appear first.")
|
||||
glossaryItems += makeGlossaryItem("FeaturedApiCollection.sortOrder", sortOrderExample)
|
||||
|
||||
lazy val operationIdExample = ConnectorField("OBPv4.0.0-getBanks", "A uniquely identify the obp endpoint on OBP instance, you can get it from Get Resource endpoints.")
|
||||
glossaryItems += makeGlossaryItem("ApiCollectionEndpoint.operationId", operationIdExample)
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import code.api.util.ErrorMessages.{InsufficientAuthorisationToCreateTransaction
|
||||
import code.api.{APIFailureNewStyle, Constant, JsonResponseException}
|
||||
import code.apicollection.{ApiCollectionTrait, MappedApiCollectionsProvider}
|
||||
import code.apicollectionendpoint.{ApiCollectionEndpointTrait, MappedApiCollectionEndpointsProvider}
|
||||
import code.featuredapicollection.{FeaturedApiCollectionTrait, MappedFeaturedApiCollectionsProvider}
|
||||
import code.atmattribute.AtmAttribute
|
||||
import code.authtypevalidation.{AuthenticationTypeValidationProvider, JsonAuthTypeValidation}
|
||||
import code.bankattribute.BankAttribute
|
||||
@ -3715,11 +3716,35 @@ object NewStyle extends MdcLoggable{
|
||||
}
|
||||
|
||||
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
|
||||
//We filter the isDefined and is isSharable collections.
|
||||
val apiCollections = featuredApiCollectionIds.map(MappedApiCollectionsProvider.getApiCollectionById).filter(_.isDefined).filter(_.head.isSharable).map(_.head)
|
||||
Future{(apiCollections.sortBy(_.apiCollectionName), callContext)}
|
||||
// First get featured collections from database, sorted by sortOrder
|
||||
val dbFeaturedApiCollections = MappedFeaturedApiCollectionsProvider.getAllFeaturedApiCollections()
|
||||
val dbApiCollectionIds = dbFeaturedApiCollections.map(_.apiCollectionId).toSet
|
||||
|
||||
// Get actual ApiCollections for database featured entries
|
||||
val dbApiCollections = dbFeaturedApiCollections
|
||||
.map(f => MappedApiCollectionsProvider.getApiCollectionById(f.apiCollectionId))
|
||||
.filter(_.isDefined)
|
||||
.filter(_.head.isSharable)
|
||||
.map(_.head)
|
||||
|
||||
// Get props-based featured IDs that are NOT in database
|
||||
val propsApiCollectionIds = APIUtil.getPropsValue("featured_api_collection_ids", "")
|
||||
.split(",")
|
||||
.map(_.trim)
|
||||
.filter(_.nonEmpty)
|
||||
.toList
|
||||
.filterNot(dbApiCollectionIds.contains)
|
||||
|
||||
// Get actual ApiCollections for props entries and sort them by name
|
||||
val propsApiCollections = propsApiCollectionIds
|
||||
.map(MappedApiCollectionsProvider.getApiCollectionById)
|
||||
.filter(_.isDefined)
|
||||
.filter(_.head.isSharable)
|
||||
.map(_.head)
|
||||
.sortBy(_.apiCollectionName)
|
||||
|
||||
// Merge: database entries first (preserve sortOrder), then props entries (sorted by name)
|
||||
Future{(dbApiCollections ++ propsApiCollections, callContext)}
|
||||
}
|
||||
|
||||
def createApiCollection(
|
||||
@ -3813,6 +3838,69 @@ object NewStyle extends MdcLoggable{
|
||||
}
|
||||
}
|
||||
|
||||
// Featured API Collections functions
|
||||
def createFeaturedApiCollection(
|
||||
apiCollectionId: String,
|
||||
sortOrder: Int,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[FeaturedApiCollectionTrait] = {
|
||||
Future(MappedFeaturedApiCollectionsProvider.createFeaturedApiCollection(apiCollectionId, sortOrder)) map {
|
||||
i => (unboxFullOrFail(i, callContext, CreateFeaturedApiCollectionError), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
def getFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[FeaturedApiCollectionTrait] = {
|
||||
Future(MappedFeaturedApiCollectionsProvider.getFeaturedApiCollectionByApiCollectionId(apiCollectionId)) map {
|
||||
i => (unboxFullOrFail(i, callContext, s"$FeaturedApiCollectionNotFound Current API_COLLECTION_ID($apiCollectionId)"), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
def getAllFeaturedApiCollectionsAdmin(callContext: Option[CallContext]): OBPReturnType[List[FeaturedApiCollectionTrait]] = {
|
||||
Future(MappedFeaturedApiCollectionsProvider.getAllFeaturedApiCollections(), callContext)
|
||||
}
|
||||
|
||||
def updateFeaturedApiCollection(
|
||||
apiCollectionId: String,
|
||||
sortOrder: Int,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[FeaturedApiCollectionTrait] = {
|
||||
Future {
|
||||
val featured = MappedFeaturedApiCollectionsProvider.getFeaturedApiCollectionByApiCollectionId(apiCollectionId)
|
||||
featured.flatMap { f =>
|
||||
MappedFeaturedApiCollectionsProvider.updateFeaturedApiCollection(f.featuredApiCollectionId, sortOrder)
|
||||
}
|
||||
} map {
|
||||
i => (unboxFullOrFail(i, callContext, s"$UpdateFeaturedApiCollectionError Current API_COLLECTION_ID($apiCollectionId)"), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
def deleteFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Boolean] = {
|
||||
Future(MappedFeaturedApiCollectionsProvider.deleteFeaturedApiCollectionByApiCollectionId(apiCollectionId)) map {
|
||||
i => (unboxFullOrFail(i, callContext, s"$DeleteFeaturedApiCollectionError Current API_COLLECTION_ID($apiCollectionId)"), callContext)
|
||||
}
|
||||
}
|
||||
|
||||
def checkFeaturedApiCollectionDoesNotExist(
|
||||
apiCollectionId: String,
|
||||
callContext: Option[CallContext]
|
||||
): OBPReturnType[Boolean] = {
|
||||
Future {
|
||||
val existing = MappedFeaturedApiCollectionsProvider.getFeaturedApiCollectionByApiCollectionId(apiCollectionId)
|
||||
existing match {
|
||||
case net.liftweb.common.Full(_) =>
|
||||
throw new RuntimeException(FeaturedApiCollectionAlreadyExists)
|
||||
case _ =>
|
||||
(true, callContext)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def createJsonSchemaValidation(validation: JsonValidation, callContext: Option[CallContext]): OBPReturnType[JsonValidation] =
|
||||
Future {
|
||||
val newValidation = JsonSchemaValidationProvider.validationProvider.vend.create(validation)
|
||||
|
||||
@ -30,7 +30,7 @@ import code.api.v5_0_0.JSONFactory500
|
||||
import code.api.v5_0_0.{ViewJsonV500, ViewsJsonV500}
|
||||
import code.api.v5_1_0.{JSONFactory510, PostCustomerLegalNameJsonV510}
|
||||
import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo}
|
||||
import code.api.v6_0_0.JSONFactory600.{AddUserToGroupResponseJsonV600, DynamicEntityDiagnosticsJsonV600, DynamicEntityIssueJsonV600, GroupEntitlementJsonV600, GroupEntitlementsJsonV600, GroupJsonV600, GroupsJsonV600, PostGroupJsonV600, PostGroupMembershipJsonV600, PostResetPasswordUrlJsonV600, PutGroupJsonV600, ReferenceTypeJsonV600, ReferenceTypesJsonV600, ResetPasswordUrlJsonV600, RoleWithEntitlementCountJsonV600, RolesWithEntitlementCountsJsonV600, ScannedApiVersionJsonV600, UpdateViewJsonV600, UserGroupMembershipJsonV600, UserGroupMembershipsJsonV600, ValidateUserEmailJsonV600, ValidateUserEmailResponseJsonV600, ViewJsonV600, ViewPermissionJsonV600, ViewPermissionsJsonV600, ViewsJsonV600, createAbacRuleJsonV600, createAbacRulesJsonV600, createActiveRateLimitsJsonV600, createCallLimitJsonV600, createRedisCallCountersJson}
|
||||
import code.api.v6_0_0.JSONFactory600.{AddUserToGroupResponseJsonV600, DynamicEntityDiagnosticsJsonV600, DynamicEntityIssueJsonV600, GroupEntitlementJsonV600, GroupEntitlementsJsonV600, GroupJsonV600, GroupsJsonV600, PostGroupJsonV600, PostGroupMembershipJsonV600, PostResetPasswordUrlJsonV600, PutGroupJsonV600, ReferenceTypeJsonV600, ReferenceTypesJsonV600, ResetPasswordUrlJsonV600, RoleWithEntitlementCountJsonV600, RolesWithEntitlementCountsJsonV600, ScannedApiVersionJsonV600, UpdateViewJsonV600, UserGroupMembershipJsonV600, UserGroupMembershipsJsonV600, ValidateUserEmailJsonV600, ValidateUserEmailResponseJsonV600, ViewJsonV600, ViewPermissionJsonV600, ViewPermissionsJsonV600, ViewsJsonV600, createAbacRuleJsonV600, createAbacRulesJsonV600, createActiveRateLimitsJsonV600, createCallLimitJsonV600, createRedisCallCountersJson, createFeaturedApiCollectionJsonV600, createFeaturedApiCollectionsJsonV600}
|
||||
import code.api.v6_0_0.{AbacRuleJsonV600, AbacRuleResultJsonV600, AbacRulesJsonV600, CacheConfigJsonV600, CacheInfoJsonV600, CacheNamespaceInfoJsonV600, CreateAbacRuleJsonV600, CreateDynamicEntityRequestJsonV600, CurrentConsumerJsonV600, DynamicEntityDefinitionJsonV600, DynamicEntityDefinitionWithCountJsonV600, DynamicEntitiesWithCountJsonV600, DynamicEntityLinksJsonV600, ExecuteAbacRuleJsonV600, GetOidcClientResponseJsonV600, InMemoryCacheStatusJsonV600, MyDynamicEntitiesJsonV600, PostVerifyUserCredentialsJsonV600, RedisCacheStatusJsonV600, RelatedLinkJsonV600, UpdateAbacRuleJsonV600, UpdateDynamicEntityRequestJsonV600, VerifyOidcClientRequestJsonV600, VerifyOidcClientResponseJsonV600}
|
||||
import code.api.v6_0_0.OBPAPI6_0_0
|
||||
import code.abacrule.{AbacRuleEngine, MappedAbacRuleProvider}
|
||||
@ -1037,7 +1037,7 @@ trait APIMethods600 {
|
||||
holder = AccountHolderJSON("Jane Smith", false),
|
||||
bank_routing = BankRoutingJsonV121("OBP", "other.bank.uk"),
|
||||
account_routings = List(AccountRoutingJsonV121("OBP", "counterparty-123")),
|
||||
metadata = null
|
||||
metadata = otherAccountMetadataJSON
|
||||
),
|
||||
details = TransactionDetailsJSON(
|
||||
`type` = "SEPA",
|
||||
@ -1047,7 +1047,7 @@ trait APIMethods600 {
|
||||
new_balance = AmountOfMoneyJsonV121("EUR", "1000.00"),
|
||||
value = AmountOfMoneyJsonV121("EUR", "100.00")
|
||||
),
|
||||
metadata = null,
|
||||
metadata = transactionMetadataJSON,
|
||||
transaction_attributes = Nil
|
||||
))),
|
||||
List(
|
||||
@ -7521,6 +7521,184 @@ trait APIMethods600 {
|
||||
}
|
||||
}
|
||||
|
||||
// Featured API Collections Management Endpoints
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
createFeaturedApiCollection,
|
||||
implementedInApiVersion,
|
||||
nameOf(createFeaturedApiCollection),
|
||||
"POST",
|
||||
"/management/api-collections/featured",
|
||||
"Create Featured Api Collection",
|
||||
s"""Add an API Collection to the featured list.
|
||||
|
|
||||
|${userAuthenticationMessage(true)}
|
||||
|
|
||||
|""".stripMargin,
|
||||
postFeaturedApiCollectionJsonV600,
|
||||
featuredApiCollectionJsonV600,
|
||||
List(
|
||||
$AuthenticatedUserIsRequired,
|
||||
UserHasMissingRoles,
|
||||
ApiCollectionNotFound,
|
||||
FeaturedApiCollectionAlreadyExists,
|
||||
CreateFeaturedApiCollectionError,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagApiCollection, apiTagApi),
|
||||
Some(List(canManageFeaturedApiCollections))
|
||||
)
|
||||
|
||||
lazy val createFeaturedApiCollection: OBPEndpoint = {
|
||||
case "management" :: "api-collections" :: "featured" :: Nil JsonPost json -> _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canManageFeaturedApiCollections, callContext)
|
||||
postJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PostFeaturedApiCollectionJsonV600", 400, callContext) {
|
||||
json.extract[PostFeaturedApiCollectionJsonV600]
|
||||
}
|
||||
// Verify the API Collection exists and is sharable
|
||||
(apiCollection, callContext) <- NewStyle.function.getApiCollectionById(postJson.api_collection_id, callContext)
|
||||
_ <- Helper.booleanToFuture(s"$ApiCollectionNotFound The API Collection must be sharable to be featured.", cc=callContext) {
|
||||
apiCollection.isSharable
|
||||
}
|
||||
// Check it's not already featured
|
||||
_ <- NewStyle.function.checkFeaturedApiCollectionDoesNotExist(postJson.api_collection_id, callContext)
|
||||
// Create the featured entry
|
||||
(featuredApiCollection, callContext) <- NewStyle.function.createFeaturedApiCollection(
|
||||
postJson.api_collection_id,
|
||||
postJson.sort_order,
|
||||
callContext
|
||||
)
|
||||
} yield {
|
||||
(JSONFactory600.createFeaturedApiCollectionJsonV600(featuredApiCollection), HttpCode.`201`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
getFeaturedApiCollectionsAdmin,
|
||||
implementedInApiVersion,
|
||||
nameOf(getFeaturedApiCollectionsAdmin),
|
||||
"GET",
|
||||
"/management/api-collections/featured",
|
||||
"Get Featured Api Collections (Admin)",
|
||||
s"""Get all featured API collections with their sort order (admin view).
|
||||
|
|
||||
|This endpoint returns the featured collections stored in the database with their sort order.
|
||||
|It is intended for administrators to manage the featured list.
|
||||
|
|
||||
|${userAuthenticationMessage(true)}
|
||||
|
|
||||
|""".stripMargin,
|
||||
EmptyBody,
|
||||
featuredApiCollectionsJsonV600,
|
||||
List(
|
||||
$AuthenticatedUserIsRequired,
|
||||
UserHasMissingRoles,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagApiCollection, apiTagApi),
|
||||
Some(List(canManageFeaturedApiCollections))
|
||||
)
|
||||
|
||||
lazy val getFeaturedApiCollectionsAdmin: OBPEndpoint = {
|
||||
case "management" :: "api-collections" :: "featured" :: Nil JsonGet _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canManageFeaturedApiCollections, callContext)
|
||||
(featuredApiCollections, callContext) <- NewStyle.function.getAllFeaturedApiCollectionsAdmin(callContext)
|
||||
} yield {
|
||||
(JSONFactory600.createFeaturedApiCollectionsJsonV600(featuredApiCollections), HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
updateFeaturedApiCollection,
|
||||
implementedInApiVersion,
|
||||
nameOf(updateFeaturedApiCollection),
|
||||
"PUT",
|
||||
"/management/api-collections/featured/API_COLLECTION_ID",
|
||||
"Update Featured Api Collection",
|
||||
s"""Update the sort order of a featured API collection.
|
||||
|
|
||||
|${userAuthenticationMessage(true)}
|
||||
|
|
||||
|""".stripMargin,
|
||||
putFeaturedApiCollectionJsonV600,
|
||||
featuredApiCollectionJsonV600,
|
||||
List(
|
||||
$AuthenticatedUserIsRequired,
|
||||
UserHasMissingRoles,
|
||||
FeaturedApiCollectionNotFound,
|
||||
UpdateFeaturedApiCollectionError,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagApiCollection, apiTagApi),
|
||||
Some(List(canManageFeaturedApiCollections))
|
||||
)
|
||||
|
||||
lazy val updateFeaturedApiCollection: OBPEndpoint = {
|
||||
case "management" :: "api-collections" :: "featured" :: apiCollectionId :: Nil JsonPut json -> _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canManageFeaturedApiCollections, callContext)
|
||||
putJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the $PutFeaturedApiCollectionJsonV600", 400, callContext) {
|
||||
json.extract[PutFeaturedApiCollectionJsonV600]
|
||||
}
|
||||
(updatedFeaturedApiCollection, callContext) <- NewStyle.function.updateFeaturedApiCollection(
|
||||
apiCollectionId,
|
||||
putJson.sort_order,
|
||||
callContext
|
||||
)
|
||||
} yield {
|
||||
(JSONFactory600.createFeaturedApiCollectionJsonV600(updatedFeaturedApiCollection), HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
deleteFeaturedApiCollection,
|
||||
implementedInApiVersion,
|
||||
nameOf(deleteFeaturedApiCollection),
|
||||
"DELETE",
|
||||
"/management/api-collections/featured/API_COLLECTION_ID",
|
||||
"Delete Featured Api Collection",
|
||||
s"""Remove an API Collection from the featured list.
|
||||
|
|
||||
|${userAuthenticationMessage(true)}
|
||||
|
|
||||
|""".stripMargin,
|
||||
EmptyBody,
|
||||
EmptyBody,
|
||||
List(
|
||||
$AuthenticatedUserIsRequired,
|
||||
UserHasMissingRoles,
|
||||
FeaturedApiCollectionNotFound,
|
||||
DeleteFeaturedApiCollectionError,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagApiCollection, apiTagApi),
|
||||
Some(List(canManageFeaturedApiCollections))
|
||||
)
|
||||
|
||||
lazy val deleteFeaturedApiCollection: OBPEndpoint = {
|
||||
case "management" :: "api-collections" :: "featured" :: apiCollectionId :: Nil JsonDelete _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canManageFeaturedApiCollections, callContext)
|
||||
(_, callContext) <- NewStyle.function.deleteFeaturedApiCollectionByApiCollectionId(apiCollectionId, callContext)
|
||||
} yield {
|
||||
(Full(true), HttpCode.`204`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,7 @@ import code.api.v3_1_0.{AccountAttributeResponseJson, RateLimit, RedisCallLimitJ
|
||||
import code.api.v4_0_0.TransactionAttributeResponseJson
|
||||
import code.api.v4_0_0.{BankAttributeBankResponseJsonV400, UserAgreementJson}
|
||||
import code.entitlement.Entitlement
|
||||
import code.featuredapicollection.FeaturedApiCollectionTrait
|
||||
import code.loginattempts.LoginAttempt
|
||||
import code.model.dataAccess.ResourceUser
|
||||
import code.users.UserAgreement
|
||||
@ -633,6 +634,26 @@ case class UpdateDynamicEntityRequestJsonV600(
|
||||
schema: net.liftweb.json.JsonAST.JObject
|
||||
)
|
||||
|
||||
// Featured API Collections (v6.0.0)
|
||||
case class PostFeaturedApiCollectionJsonV600(
|
||||
api_collection_id: String,
|
||||
sort_order: Int
|
||||
)
|
||||
|
||||
case class PutFeaturedApiCollectionJsonV600(
|
||||
sort_order: Int
|
||||
)
|
||||
|
||||
case class FeaturedApiCollectionJsonV600(
|
||||
featured_api_collection_id: String,
|
||||
api_collection_id: String,
|
||||
sort_order: Int
|
||||
)
|
||||
|
||||
case class FeaturedApiCollectionsJsonV600(
|
||||
featured_api_collections: List[FeaturedApiCollectionJsonV600]
|
||||
)
|
||||
|
||||
object JSONFactory600 extends CustomJsonFormats with MdcLoggable {
|
||||
|
||||
def createRedisCallCountersJson(
|
||||
@ -1258,6 +1279,24 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable {
|
||||
AbacRulesJsonV600(rules.map(createAbacRuleJsonV600))
|
||||
}
|
||||
|
||||
def createFeaturedApiCollectionJsonV600(
|
||||
featuredApiCollection: FeaturedApiCollectionTrait
|
||||
): FeaturedApiCollectionJsonV600 = {
|
||||
FeaturedApiCollectionJsonV600(
|
||||
featured_api_collection_id = featuredApiCollection.featuredApiCollectionId,
|
||||
api_collection_id = featuredApiCollection.apiCollectionId,
|
||||
sort_order = featuredApiCollection.sortOrder
|
||||
)
|
||||
}
|
||||
|
||||
def createFeaturedApiCollectionsJsonV600(
|
||||
featuredApiCollections: List[FeaturedApiCollectionTrait]
|
||||
): FeaturedApiCollectionsJsonV600 = {
|
||||
FeaturedApiCollectionsJsonV600(
|
||||
featuredApiCollections.map(createFeaturedApiCollectionJsonV600)
|
||||
)
|
||||
}
|
||||
|
||||
def createCacheNamespaceJsonV600(
|
||||
prefix: String,
|
||||
description: String,
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
package code.featuredapicollection
|
||||
|
||||
import code.util.MappedUUID
|
||||
import net.liftweb.mapper._
|
||||
|
||||
class FeaturedApiCollection extends FeaturedApiCollectionTrait with LongKeyedMapper[FeaturedApiCollection] with IdPK with CreatedUpdated {
|
||||
def getSingleton = FeaturedApiCollection
|
||||
|
||||
object FeaturedApiCollectionId extends MappedUUID(this)
|
||||
object ApiCollectionId extends MappedString(this, 100)
|
||||
object SortOrder extends MappedInt(this)
|
||||
|
||||
override def featuredApiCollectionId: String = FeaturedApiCollectionId.get
|
||||
override def apiCollectionId: String = ApiCollectionId.get
|
||||
override def sortOrder: Int = SortOrder.get
|
||||
}
|
||||
|
||||
object FeaturedApiCollection extends FeaturedApiCollection with LongKeyedMetaMapper[FeaturedApiCollection] {
|
||||
override def dbIndexes = UniqueIndex(FeaturedApiCollectionId) :: UniqueIndex(ApiCollectionId) :: super.dbIndexes
|
||||
}
|
||||
|
||||
trait FeaturedApiCollectionTrait {
|
||||
def featuredApiCollectionId: String
|
||||
def apiCollectionId: String
|
||||
def sortOrder: Int
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package code.featuredapicollection
|
||||
|
||||
import code.util.Helper.MdcLoggable
|
||||
import net.liftweb.common.Box
|
||||
import net.liftweb.mapper.{By, OrderBy, Ascending}
|
||||
import net.liftweb.util.Helpers.tryo
|
||||
|
||||
trait FeaturedApiCollectionsProvider {
|
||||
def createFeaturedApiCollection(
|
||||
apiCollectionId: String,
|
||||
sortOrder: Int
|
||||
): Box[FeaturedApiCollectionTrait]
|
||||
|
||||
def getFeaturedApiCollectionById(
|
||||
featuredApiCollectionId: String
|
||||
): Box[FeaturedApiCollectionTrait]
|
||||
|
||||
def getFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String
|
||||
): Box[FeaturedApiCollectionTrait]
|
||||
|
||||
def updateFeaturedApiCollection(
|
||||
featuredApiCollectionId: String,
|
||||
sortOrder: Int
|
||||
): Box[FeaturedApiCollectionTrait]
|
||||
|
||||
def getAllFeaturedApiCollections(): List[FeaturedApiCollectionTrait]
|
||||
|
||||
def deleteFeaturedApiCollectionById(
|
||||
featuredApiCollectionId: String
|
||||
): Box[Boolean]
|
||||
|
||||
def deleteFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String
|
||||
): Box[Boolean]
|
||||
}
|
||||
|
||||
object MappedFeaturedApiCollectionsProvider extends MdcLoggable with FeaturedApiCollectionsProvider {
|
||||
|
||||
override def createFeaturedApiCollection(
|
||||
apiCollectionId: String,
|
||||
sortOrder: Int
|
||||
): Box[FeaturedApiCollectionTrait] =
|
||||
tryo(
|
||||
FeaturedApiCollection
|
||||
.create
|
||||
.ApiCollectionId(apiCollectionId)
|
||||
.SortOrder(sortOrder)
|
||||
.saveMe()
|
||||
)
|
||||
|
||||
override def getFeaturedApiCollectionById(
|
||||
featuredApiCollectionId: String
|
||||
): Box[FeaturedApiCollectionTrait] =
|
||||
FeaturedApiCollection.find(By(FeaturedApiCollection.FeaturedApiCollectionId, featuredApiCollectionId))
|
||||
|
||||
override def getFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String
|
||||
): Box[FeaturedApiCollectionTrait] =
|
||||
FeaturedApiCollection.find(By(FeaturedApiCollection.ApiCollectionId, apiCollectionId))
|
||||
|
||||
override def updateFeaturedApiCollection(
|
||||
featuredApiCollectionId: String,
|
||||
sortOrder: Int
|
||||
): Box[FeaturedApiCollectionTrait] = {
|
||||
FeaturedApiCollection.find(By(FeaturedApiCollection.FeaturedApiCollectionId, featuredApiCollectionId)).map { featured =>
|
||||
featured
|
||||
.SortOrder(sortOrder)
|
||||
.saveMe()
|
||||
}
|
||||
}
|
||||
|
||||
override def getAllFeaturedApiCollections(): List[FeaturedApiCollectionTrait] =
|
||||
FeaturedApiCollection.findAll(OrderBy(FeaturedApiCollection.SortOrder, Ascending))
|
||||
|
||||
override def deleteFeaturedApiCollectionById(
|
||||
featuredApiCollectionId: String
|
||||
): Box[Boolean] =
|
||||
FeaturedApiCollection.find(By(FeaturedApiCollection.FeaturedApiCollectionId, featuredApiCollectionId)).map(_.delete_!)
|
||||
|
||||
override def deleteFeaturedApiCollectionByApiCollectionId(
|
||||
apiCollectionId: String
|
||||
): Box[Boolean] =
|
||||
FeaturedApiCollection.find(By(FeaturedApiCollection.ApiCollectionId, apiCollectionId)).map(_.delete_!)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user