From 7cec58749cc791b2b6796e13b1153d8506b0ef05 Mon Sep 17 00:00:00 2001 From: simonredfern Date: Fri, 30 Jan 2026 00:12:18 +0100 Subject: [PATCH] Added getOidcClient --- .../main/scala/code/api/util/ApiRole.scala | 3 + .../scala/code/api/v6_0_0/APIMethods600.scala | 65 ++++++++++++++++++- .../code/api/v6_0_0/JSONFactory6.0.0.scala | 9 +++ 3 files changed, 76 insertions(+), 1 deletion(-) 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 58021f2ec..442e67b4b 100644 --- a/obp-api/src/main/scala/code/api/util/ApiRole.scala +++ b/obp-api/src/main/scala/code/api/util/ApiRole.scala @@ -285,6 +285,9 @@ object ApiRole extends MdcLoggable{ case class CanVerifyOidcClient(requiresBankId: Boolean = false) extends ApiRole lazy val canVerifyOidcClient = CanVerifyOidcClient() + case class CanGetOidcClient(requiresBankId: Boolean = false) extends ApiRole + lazy val canGetOidcClient = CanGetOidcClient() + case class CanCreateTransactionType(requiresBankId: Boolean = true) extends ApiRole lazy val canCreateTransactionType = CanCreateTransactionType() diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index de79ba6b7..35f98d696 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -31,7 +31,7 @@ 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.{AbacRuleJsonV600, AbacRuleResultJsonV600, AbacRulesJsonV600, CacheConfigJsonV600, CacheInfoJsonV600, CacheNamespaceInfoJsonV600, CreateAbacRuleJsonV600, CreateDynamicEntityRequestJsonV600, CurrentConsumerJsonV600, DynamicEntityDefinitionJsonV600, DynamicEntityDefinitionWithCountJsonV600, DynamicEntitiesWithCountJsonV600, DynamicEntityLinksJsonV600, ExecuteAbacRuleJsonV600, InMemoryCacheStatusJsonV600, MyDynamicEntitiesJsonV600, PostVerifyUserCredentialsJsonV600, RedisCacheStatusJsonV600, RelatedLinkJsonV600, UpdateAbacRuleJsonV600, UpdateDynamicEntityRequestJsonV600, VerifyOidcClientRequestJsonV600, VerifyOidcClientResponseJsonV600} +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} import code.metrics.APIMetrics @@ -7458,6 +7458,69 @@ trait APIMethods600 { } } + staticResourceDocs += ResourceDoc( + getOidcClient, + implementedInApiVersion, + nameOf(getOidcClient), + "GET", + "/oidc/clients/CLIENT_ID", + "Get OIDC Client", + s"""Gets an OIDC/OAuth2 client's metadata by client_id. + | + |Returns client information including name, consumer_id, redirect_uris, and enabled status. + |This endpoint does not verify the client secret - use POST /oidc/clients/verify for authentication. + | + |${userAuthenticationMessage(true)} + |""", + EmptyBody, + GetOidcClientResponseJsonV600( + client_id = "abc123def456", + client_name = "My Application", + consumer_id = "7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh", + redirect_uris = List("https://app.example.com/callback"), + enabled = true + ), + List( + $AuthenticatedUserIsRequired, + UserHasMissingRoles, + UnknownError + ), + List(apiTagOIDC, apiTagConsumer, apiTagOAuth), + Some(List(canGetOidcClient)) + ) + + lazy val getOidcClient: OBPEndpoint = { + case "oidc" :: "clients" :: clientId :: Nil JsonGet _ => { + cc => implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- authenticatedAccess(cc) + _ <- if(isSuperAdmin(u.userId)) Future.successful(Full(Unit)) + else NewStyle.function.hasEntitlement("", u.userId, canGetOidcClient, callContext) + consumerBox <- Future { + Consumers.consumers.vend.getConsumerByConsumerKey(clientId) + } + consumer <- NewStyle.function.tryons(s"OBP-OIDC-003: Client not found: $clientId", 404, callContext) { + consumerBox match { + case Full(c) => c + case _ => throw new RuntimeException("Client not found") + } + } + } yield { + val redirectUris = Option(consumer.redirectURL.get) + .filter(_.nonEmpty) + .map(_.split("[,\\s]+").map(_.trim).filter(_.nonEmpty).toList) + .getOrElse(List.empty) + (GetOidcClientResponseJsonV600( + client_id = clientId, + client_name = consumer.name.get, + consumer_id = consumer.consumerId.get, + redirect_uris = redirectUris, + enabled = consumer.isActive.get + ), HttpCode.`200`(callContext)) + } + } + } + } } diff --git a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala index c6d904d73..8b721a83f 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala @@ -91,6 +91,15 @@ case class VerifyOidcClientResponseJsonV600( redirect_uris: Option[List[String]] = None ) +// OIDC Client Get (metadata lookup without secret verification) +case class GetOidcClientResponseJsonV600( + client_id: String, + client_name: String, + consumer_id: String, + redirect_uris: List[String], + enabled: Boolean +) + case class CallLimitPostJsonV600( from_date: java.util.Date, to_date: java.util.Date,