feature/add revoke consent endpoint for user

This commit is contained in:
hongwei 2025-05-28 14:28:44 +02:00
parent 5892160670
commit 904009c49f
2 changed files with 59 additions and 10 deletions

View File

@ -28,7 +28,7 @@ package code.api.v4_0_0
import code.api.OBPRestHelper
import code.api.util.APIUtil.{OBPEndpoint, getAllowedEndpoints}
import code.api.util.{APIUtil, VersionedOBPApis}
import code.api.util.VersionedOBPApis
import code.api.v1_3_0.APIMethods130
import code.api.v1_4_0.APIMethods140
import code.api.v2_0_0.APIMethods200
@ -39,7 +39,7 @@ import code.api.v3_0_0.custom.CustomAPIMethods300
import code.api.v3_1_0.{APIMethods310, OBPAPI3_1_0}
import code.util.Helper.MdcLoggable
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.util.{ApiVersion,ApiVersionStatus}
import com.openbankproject.commons.util.{ApiVersion, ApiVersionStatus}
import net.liftweb.common.{Box, Full}
import net.liftweb.http.{LiftResponse, PlainTextResponse}
import org.apache.http.HttpStatus
@ -63,6 +63,7 @@ object OBPAPI4_0_0 extends OBPRestHelper with APIMethods130 with APIMethods140 w
nameOf(Implementations1_2_1.addPermissionForUserForBankAccountForOneView) ::
nameOf(Implementations1_2_1.removePermissionForUserForBankAccountForOneView) ::
nameOf(Implementations3_1_0.createAccount) ::
nameOf(Implementations3_1_0.revokeConsent) :://this endpoint is not restful, we do not support it in V510.
Nil
// if old version ResourceDoc objects have the same name endpoint with new version, omit old version ResourceDoc.

View File

@ -14,17 +14,17 @@ import code.api.util.NewStyle.HttpCode
import code.api.util.NewStyle.function.extractQueryParams
import code.api.util.X509.{getCommonName, getEmailAddress, getOrganization}
import code.api.util._
import code.api.util.newstyle.{BalanceNewStyle, RegulatedEntityAttributeNewStyle}
import code.api.util.newstyle.Consumer.createConsumerNewStyle
import code.api.util.newstyle.RegulatedEntityNewStyle.{createRegulatedEntityNewStyle, deleteRegulatedEntityNewStyle, getRegulatedEntitiesNewStyle, getRegulatedEntityByEntityIdNewStyle}
import code.api.util.newstyle.{BalanceNewStyle, RegulatedEntityAttributeNewStyle}
import code.api.v2_0_0.AccountsHelper.{accountTypeFilterText, getFilteredCoreAccounts}
import code.api.v2_1_0.{ConsumerRedirectUrlJSON, JSONFactory210}
import code.api.v3_0_0.JSONFactory300
import code.api.v3_0_0.JSONFactory300.createAggregateMetricJson
import code.api.v3_1_0.{ConsentChallengeJsonV310, ConsentJsonV310, PostConsentBodyCommonJson, PostConsentEmailJsonV310, PostConsentPhoneJsonV310}
import code.api.v3_1_0.JSONFactory310.{createBadLoginStatusJson, createConsumerJSON, createRefreshUserJson}
import code.api.v3_1_0.JSONFactory310.{createBadLoginStatusJson, createConsumerJSON}
import code.api.v3_1_0._
import code.api.v4_0_0.JSONFactory400.{createAccountBalancesJson, createBalancesJson, createNewCoreBankAccountJson}
import code.api.v4_0_0.{JSONFactory400, PostAccountAccessJsonV400, PostApiCollectionJson400, PutConsentStatusJsonV400, PutConsentUserJsonV400, RevokedJsonV400}
import code.api.v4_0_0._
import code.api.v5_0_0.JSONFactory500
import code.api.v5_1_0.JSONFactory510.{createConsentsInfoJsonV510, createConsentsJsonV510, createRegulatedEntitiesJson, createRegulatedEntityJson}
import code.atmattribute.AtmAttribute
@ -34,9 +34,8 @@ import code.consumer.Consumers
import code.entitlement.Entitlement
import code.loginattempts.LoginAttempt
import code.metrics.APIMetrics
import code.metrics.MappedMetric.userId
import code.model.{AppType, Consumer}
import code.model.dataAccess.{AuthUser, MappedBankAccount}
import code.model.{AppType, Consumer}
import code.regulatedentities.MappedRegulatedEntityProvider
import code.userlocks.UserLocksProvider
import code.users.Users
@ -47,7 +46,7 @@ import code.views.system.{AccountAccess, ViewDefinition}
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model._
import com.openbankproject.commons.model.enums.{AtmAttributeType, ConsentType, RegulatedEntityAttributeType, StrongCustomerAuthentication, TransactionRequestStatus, UserAttributeType}
import com.openbankproject.commons.model.enums.{TransactionRequestStatus, _}
import com.openbankproject.commons.util.{ApiVersion, ScannedApiVersion}
import net.liftweb.common.Full
import net.liftweb.http.rest.RestHelper
@ -57,7 +56,6 @@ import net.liftweb.mapper.By
import net.liftweb.util.Helpers.tryo
import net.liftweb.util.{Helpers, Props, StringHelpers}
import java.text.SimpleDateFormat
import java.time.{LocalDate, ZoneId}
import java.util.Date
import scala.collection.immutable.{List, Nil}
@ -1883,7 +1881,57 @@ trait APIMethods510 {
}
}
resourceDocs += ResourceDoc(
revokeMyConsent,
implementedInApiVersion,
nameOf(revokeMyConsent),
"Delete",
"/my/consents/CONSENT_ID",
"Revoke My Consent",
s"""
|Revoke Consent for current user specified by CONSENT_ID
|
|There are a few reasons you might need to revoke an applications access to a users account:
| - The user explicitly wishes to revoke the applications access
| - You as the service provider have determined an application is compromised or malicious, and want to disable it
| - etc.
|
|Please note that this endpoint only supports the case:: "The user explicitly wishes to revoke the applications access"
|
|OBP as a resource server stores access tokens in a database, then it is relatively easy to revoke some token that belongs to a particular user.
|The status of the token is changed to "REVOKED" so the next time the revoked client makes a request, their token will fail to validate.
|
|${userAuthenticationMessage(true)}
|
""".stripMargin,
EmptyBody,
revokedConsentJsonV310,
List(
$UserNotLoggedIn,
BankNotFound,
UnknownError
),
List(apiTagConsent, apiTagPSD2AIS, apiTagPsd2))
lazy val revokeMyConsent: OBPEndpoint = {
case "my" :: "consents" :: consentId :: Nil JsonDelete _ => {
cc => implicit val ec = EndpointContext(Some(cc))
for {
(Full(u), callContext) <- SS.user
consent <- Future(Consents.consentProvider.vend.getConsentByConsentId(consentId)) map {
unboxFullOrFail(_, callContext, ConsentNotFound)
}
_ <- Helper.booleanToFuture(failMsg = ConsentNotFound, cc=callContext) {
consent.mUserId == u.userId
}
consent <- Future(Consents.consentProvider.vend.revoke(consentId)) map {
i => connectorEmptyResponse(i, callContext)
}
} yield {
(ConsentJsonV310(consent.consentId, consent.jsonWebToken, consent.status), HttpCode.`200`(callContext))
}
}
}
val generalObpConsentText: String =
s"""
|