diff --git a/obp-api/src/main/scala/code/api/util/APIUtil.scala b/obp-api/src/main/scala/code/api/util/APIUtil.scala index 86c1842d8..a5982830d 100644 --- a/obp-api/src/main/scala/code/api/util/APIUtil.scala +++ b/obp-api/src/main/scala/code/api/util/APIUtil.scala @@ -28,59 +28,52 @@ TESOBE (http://www.tesobe.com/) package code.api.util import bootstrap.liftweb.CustomDBVendor - -import java.io.InputStream -import java.net.URLDecoder -import java.nio.charset.Charset -import java.text.{ParsePosition, SimpleDateFormat} -import java.util.concurrent.ConcurrentHashMap -import java.util.{Calendar, Date, TimeZone, UUID} -import code.UserRefreshes.UserRefreshes import code.accountholders.AccountHolders import code.api.Constant._ import code.api.OAuthHandshake._ import code.api.UKOpenBanking.v2_0_0.OBP_UKOpenBanking_200 import code.api.UKOpenBanking.v3_1_0.OBP_UKOpenBanking_310 +import code.api._ import code.api.berlin.group.v1.OBP_BERLIN_GROUP_1 +import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{ErrorMessageBG, ErrorMessagesBG} import code.api.dynamic.endpoint.OBPAPIDynamicEndpoint import code.api.dynamic.endpoint.helper.{DynamicEndpointHelper, DynamicEndpoints} +import code.api.dynamic.entity.OBPAPIDynamicEntity +import code.api.dynamic.entity.helper.DynamicEntityHelper import code.api.oauth1a.Arithmetics import code.api.oauth1a.OauthParams._ import code.api.util.APIUtil.ResourceDoc.{findPathVariableNames, isPathVariable} -import code.api.util.ApiRole.{canCreateAnyTransactionRequest, canCreateProduct, canCreateProductAtAnyBank} +import code.api.util.ApiRole._ import code.api.util.ApiTag.{ResourceDocTag, apiTagBank} +import code.api.util.FutureUtil.{EndpointContext, EndpointTimeout} import code.api.util.Glossary.GlossaryItem -import code.api.util.RateLimitingJson.CallLimit import code.api.v1_2.ErrorMessage import code.api.v2_0_0.CreateEntitlementJSON -import code.api.dynamic.endpoint.helper.DynamicEndpointHelper -import code.api.dynamic.entity.OBPAPIDynamicEntity -import code.api._ -import code.api.berlin.group.v1_3.JSONFactory_BERLIN_GROUP_1_3.{ErrorMessageBG, ErrorMessagesBG} -import code.api.dynamic.entity.helper.DynamicEntityHelper -import code.api.v5_0_0.OBPAPI5_0_0 +import code.api.v2_2_0.OBPAPI2_2_0.Implementations2_2_0 import code.api.v5_1_0.OBPAPI5_1_0 -import code.api.{DirectLogin, _} import code.authtypevalidation.AuthenticationTypeValidationProvider import code.bankconnectors.Connector import code.consumer.Consumers import code.customer.CustomerX import code.entitlement.Entitlement +import code.etag.MappedETag import code.metrics._ import code.model._ import code.model.dataAccess.AuthUser import code.scope.Scope import code.usercustomerlinks.UserCustomerLink +import code.users.Users import code.util.Helper.{MdcLoggable, ObpS, SILENCE_IS_GOLDEN} import code.util.{Helper, JsonSchemaUtil} +import code.views.system.{AccountAccess, ViewDefinition} import code.views.{MapperViews, Views} import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue import com.alibaba.ttl.internal.javassist.CannotCompileException import com.github.dwickern.macros.NameOf.{nameOf, nameOfType} import com.openbankproject.commons.ExecutionContext.Implicits.global +import com.openbankproject.commons.model._ import com.openbankproject.commons.model.enums.StrongCustomerAuthentication.SCA import com.openbankproject.commons.model.enums.{ContentParam, PemCertificateRole, StrongCustomerAuthentication} -import com.openbankproject.commons.model._ import com.openbankproject.commons.util.Functions.Implicits._ import com.openbankproject.commons.util.Functions.Memo import com.openbankproject.commons.util._ @@ -97,38 +90,26 @@ import net.liftweb.json import net.liftweb.json.JsonAST.{JField, JNothing, JObject, JString, JValue} import net.liftweb.json.JsonParser.ParseException import net.liftweb.json._ +import net.liftweb.mapper.By import net.liftweb.util.Helpers._ import net.liftweb.util._ import org.apache.commons.io.IOUtils import org.apache.commons.lang3.StringUtils +import java.io.InputStream +import java.net.URLDecoder +import java.nio.charset.Charset +import java.security.AccessControlException +import java.text.{ParsePosition, SimpleDateFormat} +import java.util.concurrent.ConcurrentHashMap +import java.util.regex.Pattern +import java.util.{Calendar, Date, UUID} import scala.collection.JavaConverters._ import scala.collection.immutable.{List, Nil} -import scala.collection.{immutable, mutable} -import com.openbankproject.commons.ExecutionContext.Implicits.global -import com.openbankproject.commons.util.{ApiVersion, Functions, JsonAble, ReflectUtils, ScannedApiVersion} -import com.openbankproject.commons.util.Functions.Implicits._ -import com.openbankproject.commons.util.Functions.Memo -import javassist.{ClassPool, LoaderClassPath} -import javassist.expr.{ExprEditor, MethodCall} -import org.apache.commons.io.IOUtils -import org.apache.commons.lang3.StringUtils - -import java.security.AccessControlException -import java.util.regex.Pattern -import code.api.util.FutureUtil.{EndpointContext, EndpointTimeout} -import code.api.v2_1_0.OBPAPI2_1_0.Implementations2_1_0 -import code.api.v2_2_0.OBPAPI2_2_0.Implementations2_2_0 -import code.etag.MappedETag -import code.users.Users -import code.views.system.{AccountAccess, ViewDefinition} -import net.liftweb.mapper.By - -import scala.collection.mutable import scala.collection.mutable.{ArrayBuffer, ListBuffer} +import scala.collection.{immutable, mutable} import scala.concurrent.Future import scala.io.BufferedSource -import scala.util.Either import scala.util.control.Breaks.{break, breakable} import scala.xml.{Elem, XML} @@ -3368,9 +3349,9 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ * eg: CounterpartyId, because we use this Id both for Counterparty and counterpartyMetaData by some input fields. */ def createOBPId(in:String)= { - import java.security.MessageDigest - import net.liftweb.util.SecurityHelpers._ + + import java.security.MessageDigest def base64EncodedSha256(in: String) = base64EncodeURLSafe(MessageDigest.getInstance("SHA-256").digest(in.getBytes("UTF-8"))).stripSuffix("=") base64EncodedSha256(in) @@ -4745,6 +4726,10 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{ val createProductEntitlements = canCreateProduct :: canCreateProductAtAnyBank :: Nil val createProductEntitlementsRequiredText = UserHasMissingRoles + createProductEntitlements.mkString(" or ") + + val createAtmEntitlements = canCreateAtm :: canCreateAtmAtAnyBank :: Nil + + val createAtmEntitlementsRequiredText = UserHasMissingRoles + createAtmEntitlements.mkString(" or ") val productHiearchyAndCollectionNote = """ diff --git a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala index d93462b75..b9d20ea0f 100644 --- a/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala +++ b/obp-api/src/main/scala/code/api/v2_2_0/APIMethods220.scala @@ -13,6 +13,7 @@ import code.api.v1_2_1.{CreateViewJsonV121, JSONFactory, UpdateViewJsonV121} import code.api.v2_0_0.OBPAPI2_0_0 import code.api.v2_1_0._ import code.api.v2_2_0.JSONFactory220.transformV220ToBranch +import code.api.v4_0_0.{AtmJsonV400, JSONFactory400} import code.bankconnectors._ import code.consumer.Consumers import code.entitlement.Entitlement @@ -589,10 +590,6 @@ trait APIMethods220 { } } - - val createAtmEntitlementsRequiredForSpecificBank = canCreateAtm :: Nil - val createAtmEntitlementsRequiredForAnyBank = canCreateAtmAtAnyBank :: Nil - resourceDocs += ResourceDoc( createAtm, implementedInApiVersion, @@ -621,17 +618,20 @@ trait APIMethods220 { lazy val createAtm: OBPEndpoint = { case "banks" :: BankId(bankId) :: "atms" :: Nil JsonPost json -> _ => { - cc => + cc => implicit val ec = EndpointContext(Some(cc)) for { - u <- cc.user ?~!ErrorMessages.UserNotLoggedIn - (bank, callContext) <- BankX(bankId, Some(cc)) ?~! BankNotFound - _ <- NewStyle.function.hasAllEntitlements(bank.bankId.value, u.userId, createAtmEntitlementsRequiredForSpecificBank, createAtmEntitlementsRequiredForAnyBank, callContext) - atmJson <- tryo {json.extract[AtmJsonV220]} ?~! ErrorMessages.InvalidJsonFormat - atm <- JSONFactory220.transformToAtmFromV220(atmJson) ?~! {ErrorMessages.CouldNotTransformJsonToInternalModel + " Atm"} - success <- Connector.connector.vend.createOrUpdateAtmLegacy(atm) + (Full(u), callContext) <- authenticatedAccess(cc) + atmJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the ${classOf[AtmJsonV400]}", 400, callContext) { + json.extract[AtmJsonV220] + } + _ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = createAtmEntitlementsRequiredText)(bankId.value, u.userId, createAtmEntitlements, callContext) + _ <- Helper.booleanToFuture(s"$InvalidJsonValue BANK_ID has to be the same in the URL and Body", 400, callContext){atmJsonV400.bank_id == bankId.value} + atm <- NewStyle.function.tryons(ErrorMessages.CouldNotTransformJsonToInternalModel + " Atm", 400, callContext) { + JSONFactory220.transformToAtmFromV220(atmJson).head + } + (atm, callContext) <- NewStyle.function.createOrUpdateAtm(atm, callContext) } yield { - val json = JSONFactory220.createAtmJson(success) - createdJsonResponse(Extraction.decompose(json)) + (JSONFactory220.createAtmJson(atm), HttpCode.`201`(callContext)) } } } diff --git a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala index 31ddf3fb1..4b0f85f5b 100644 --- a/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala +++ b/obp-api/src/main/scala/code/api/v3_0_0/APIMethods300.scala @@ -1,7 +1,6 @@ package code.api.v3_0_0 import java.util.regex.Pattern - import code.accountattribute.AccountAttributeX import code.accountholders.AccountHolders import code.api.{APIFailureNewStyle, Constant} @@ -46,7 +45,8 @@ import com.openbankproject.commons.ExecutionContext.Implicits.global import scala.concurrent.Future import code.api.v2_0_0.AccountsHelper._ -import code.api.v4_0_0.JSONFactory400 +import code.api.v2_2_0.{AtmJsonV220, JSONFactory220} +import code.api.v4_0_0.{AtmJsonV400, JSONFactory400} import code.model import com.openbankproject.commons.dto.CustomerAndAttribute import com.openbankproject.commons.util.ApiVersion @@ -1235,18 +1235,20 @@ trait APIMethods300 { lazy val createAtm: OBPEndpoint = { case "banks" :: BankId(bankId) :: "atms" :: Nil JsonPost json -> _ => { - cc => + cc => implicit val ec = EndpointContext(Some(cc)) for { - u <- cc.user ?~!ErrorMessages.UserNotLoggedIn - (bank, _) <- BankX(bankId, Some(cc)) ?~! BankNotFound - _ <- NewStyle.function.hasAllEntitlements(bank.bankId.value, u.userId, createAtmEntitlementsRequiredForSpecificBank, createAtmEntitlementsRequiredForAnyBank, cc.callContext) - atmJson <- tryo {json.extract[AtmJsonV300]} ?~! ErrorMessages.InvalidJsonFormat - atm <- transformToAtmFromV300(atmJson) ?~! {ErrorMessages.CouldNotTransformJsonToInternalModel + " Atm"} - _ <- booleanToBox(atmJson.bank_id == bank.bankId.value, s"$InvalidJsonValue BANK_ID has to be the same in the URL and Body") - success <- Connector.connector.vend.createOrUpdateAtmLegacy(atm) + (Full(u), callContext) <- authenticatedAccess(cc) + atmJson <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the ${classOf[AtmJsonV400]}", 400, callContext) { + json.extract[AtmJsonV300] + } + _ <- NewStyle.function.hasAtLeastOneEntitlement(failMsg = createAtmEntitlementsRequiredText)(bankId.value, u.userId, createAtmEntitlements, callContext) + _ <- Helper.booleanToFuture(s"$InvalidJsonValue BANK_ID has to be the same in the URL and Body", 400, callContext){atmJsonV400.bank_id == bankId.value} + atm <- NewStyle.function.tryons(ErrorMessages.CouldNotTransformJsonToInternalModel + " Atm", 400, callContext) { + transformToAtmFromV300(atmJson).head + } + (atm, callContext) <- NewStyle.function.createOrUpdateAtm(atm, callContext) } yield { - val json = JSONFactory300.createAtmJsonV300(success) - createdJsonResponse(Extraction.decompose(json), 201) + (JSONFactory300.createAtmJsonV300(atm), HttpCode.`201`(callContext)) } } } diff --git a/obp-api/src/main/scala/code/bankconnectors/Connector.scala b/obp-api/src/main/scala/code/bankconnectors/Connector.scala index 4311c522a..eec3a02cc 100644 --- a/obp-api/src/main/scala/code/bankconnectors/Connector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/Connector.scala @@ -1033,9 +1033,6 @@ trait Connector extends MdcLoggable { bankRoutingScheme: String, bankRoutingAddress: String ): Box[Bank] = Failure(setUnimplementedError(nameOf(createOrUpdateBank _))) - - - def createOrUpdateAtmLegacy(atm: AtmT): Box[AtmT] = Failure(setUnimplementedError(nameOf(createOrUpdateAtmLegacy _))) def createOrUpdateAtm(atm: AtmT, callContext: Option[CallContext]): OBPReturnType[Box[AtmT]] = Future{Failure(setUnimplementedError(nameOf(createOrUpdateAtm _)))} diff --git a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala index 9a1108445..996db1e49 100644 --- a/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala +++ b/obp-api/src/main/scala/code/bankconnectors/LocalMappedConnector.scala @@ -2658,7 +2658,10 @@ object LocalMappedConnector extends Connector with MdcLoggable { } override def createOrUpdateAtm(atm: AtmT, callContext: Option[CallContext]): OBPReturnType[Box[AtmT]] = Future{ - (createOrUpdateAtmLegacy(atm), callContext) + ( + Atms.atmsProvider.vend.createOrUpdateAtm(atm), + callContext + ) } override def deleteAtm(atm: AtmT, callContext: Option[CallContext]): OBPReturnType[Box[Boolean]] = Future { @@ -2768,12 +2771,6 @@ object LocalMappedConnector extends Connector with MdcLoggable { ), callContext) } - - - override def createOrUpdateAtmLegacy(atm: AtmT): Box[AtmT] = { - Atms.atmsProvider.vend.createOrUpdateAtm(atm) - } - override def createOrUpdateProductFee( bankId: BankId, productCode: ProductCode, diff --git a/obp-commons/src/main/scala/com/openbankproject/commons/dto/JsonsTransfer.scala b/obp-commons/src/main/scala/com/openbankproject/commons/dto/JsonsTransfer.scala index b11a085ab..0f1d1a0f4 100644 --- a/obp-commons/src/main/scala/com/openbankproject/commons/dto/JsonsTransfer.scala +++ b/obp-commons/src/main/scala/com/openbankproject/commons/dto/JsonsTransfer.scala @@ -1266,11 +1266,6 @@ case class InBoundCreateOrUpdateBank(status: Status, data: BankCommons) extends override val inboundAdapterCallContext: InboundAdapterCallContext = InboundAdapterCallContext() } -case class OutBoundCreateOrUpdateAtmLegacy(atm: AtmT) extends TopicTrait -case class InBoundCreateOrUpdateAtmLegacy(status: Status, data: AtmTCommons) extends InBoundTrait[AtmTCommons] { - override val inboundAdapterCallContext: InboundAdapterCallContext = InboundAdapterCallContext() -} - case class OutBoundCreateOrUpdateProduct(bankId: String, code: String, parentProductCode: Option[String], name: String, category: String, family: String, superFamily: String, moreInfoUrl: String, termsAndConditionsUrl: String, details: String, description: String, metaLicenceId: String, metaLicenceName: String) extends TopicTrait case class InBoundCreateOrUpdateProduct(status: Status, data: ProductCommons) extends InBoundTrait[ProductCommons] { override val inboundAdapterCallContext: InboundAdapterCallContext = InboundAdapterCallContext()