Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions services/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,26 @@
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/clients.yaml</inputSpec>
<generatorName>jaxrs-spec</generatorName>
<additionalProperties>interfaceOnly=true,useSwaggerAnnotations=false</additionalProperties>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
<apiPackage>org.keycloak.services.resources.admin</apiPackage>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ public AdminConsole getAdminConsole(final @PathParam("realm") String name) {
return service;
}

@Path("v2/clients")
public ClientExampleResource getNewClientResource() {
return new ClientExampleResource();
}


protected AdminAuth authenticateRealmAdminRequest(HttpHeaders headers) {
String tokenString = AppAuthManager.extractAuthorizationHeaderToken(headers);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.keycloak.services.resources.admin;

import java.util.ArrayList;
import java.util.List;

import org.openapitools.model.Client;
import org.openapitools.model.PartialClient;

/**
* The interface is generated and we "only" need to implement them.
* PartialClient is to have type save responses instead of passing in `briefRepresentation` and only partially filling the entity
*/
public class ClientExampleResource implements ClientsApi {
@Override
public void createClient(Client client) {

}

@Override
public void deleteClient(String clientId) {

}

@Override
public Client getClient(String clientId) {
return null;
}

@Override
public List<PartialClient> getClients() {
List<PartialClient> partialClients = new ArrayList<>(2);
final PartialClient client = new PartialClient();
client.id("71e7f5d7-a093-4ddc-8847-3f45be0a662b");
client.setClientId("account");
partialClients.add(client);
final PartialClient client2 = new PartialClient();
client2.id("4389e5be-22b7-44d9-9c9c-ee4bc6da0159");
client2.setClientId("security-admin-console");
partialClients.add(client2);

return partialClients;
}

@Override
public void updateClient(String clientId, Client client) {

}
}
271 changes: 271 additions & 0 deletions services/src/main/resources/clients.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
openapi: 3.0.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be the latest 3.1.0 OpenAPI version can be used or at least version 3.0.3 which is supported by most of modern tools.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

info:
title: Admin Rest API v2
version: '1.0'
description: 'Example of how we could create a contract fist based rest api'
servers:
-
url: '{scheme}://localhost:8180/{basePath}'
variables:
scheme:
enum:
- https
- http
default: http
basePath:
default: /admin/realms/
paths:
/clients:
summary: Path used to manage the list of clients.
description: >-
The REST endpoint/path used to list and create zero or more `Client` entities. This path contains
a `GET` and `POST` operation to perform the list and create tasks, respectively.
get:
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PartialClient'
description: Successful response - returns an array of `PartialClient` entities.
operationId: getClients
summary: List All Clients
description: Gets a list of all `PartialClient` entities.
post:
requestBody:
description: A new `Client` to be created.
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
required: true
responses:
'201':
description: Successful response.
operationId: createClient
summary: Create a Client
description: Creates a new instance of a `Client`.
'/clients/{clientId}':
summary: Path used to manage a single Client.
description: >-
The REST endpoint/path used to get, update, and delete single instances of an `Client`. This path
contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks,
respectively.
get:
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
description: Successful response - returns a single `Client`.
operationId: getClient
summary: Get a Client
description: Gets the details of a single instance of a `Client`.
put:
requestBody:
description: Updated `Client` information.
content:
application/json:
schema:
$ref: '#/components/schemas/Client'
required: true
responses:
'202':
description: Successful response.
operationId: updateClient
summary: Update a Client
description: Updates an existing `Client`.
delete:
responses:
'204':
description: Successful response.
operationId: deleteClient
summary: Delete a Client
description: Deletes an existing `Client`.
parameters:
-
name: clientId
description: A unique identifier for a `Client`.
schema:
type: string
in: path
required: true
components:
schemas:
ErrorModel:
type: object
properties:
code:
type: string
Client:
title: Root Type for Client
description: ''
required:
- id
- clientId
- protocol
- access
type: object
properties:
id:
type: string
readOnly: true
clientId:
type: string
rootUrl:
type: string
adminUrl:
type: string
surrogateAuthRequired:
type: boolean
enabled:
type: boolean
alwaysDisplayInConsole:
type: boolean
clientAuthenticatorType:
type: string
redirectUris:
type: array
items:
type: string
webOrigins:
type: array
items:
type: string
notBefore:
format: int32
type: integer
bearerOnly:
type: boolean
consentRequired:
type: boolean
standardFlowEnabled:
type: boolean
implicitFlowEnabled:
type: boolean
directAccessGrantsEnabled:
type: boolean
serviceAccountsEnabled:
type: boolean
publicClient:
type: boolean
frontchannelLogout:
type: boolean
protocol:
type: string
attributes:
type: object
properties:
backchannel.logout.session.required:
type: string
backchannel.logout.revoke.offline.tokens:
type: string
authenticationFlowBindingOverrides:
type: object
fullScopeAllowed:
type: boolean
nodeReRegistrationTimeout:
format: int32
type: integer
defaultClientScopes:
type: array
items:
type: string
optionalClientScopes:
type: array
items:
type: string
access:
properties:
view:
type: boolean
configure:
type: boolean
manage:
type: boolean
example:
id: bfae6a3b-ff81-48ee-a545-99d300b0c09d
clientId: security-admin-console-v2
rootUrl: 'http://localhost:8080/'
adminUrl: 'http://localhost:8080/'
surrogateAuthRequired: false
enabled: true
alwaysDisplayInConsole: false
clientAuthenticatorType: client-secret
redirectUris:
- 'http://localhost:8080/*'
webOrigins:
- 'http://localhost:8080'
notBefore: 0
bearerOnly: false
consentRequired: false
standardFlowEnabled: true
implicitFlowEnabled: false
directAccessGrantsEnabled: true
serviceAccountsEnabled: false
publicClient: true
frontchannelLogout: false
protocol: openid-connect
attributes:
backchannel.logout.session.required: 'true'
backchannel.logout.revoke.offline.tokens: 'false'
authenticationFlowBindingOverrides: {}
fullScopeAllowed: true
nodeReRegistrationTimeout: -1
defaultClientScopes:
- web-origins
- roles
- profile
- email
optionalClientScopes:
- address
- phone
- offline_access
- microprofile-jwt
access:
view: true
configure: true
manage: true
PartialClient:
description: ''
required:
- id
- clientId
type: object
properties:
id:
description: ''
type: string
readOnly: true
clientId:
description: ''
type: string
protocol:
description: ''
type: string
description:
description: ''
type: string
baseUrl:
description: ''
type: string
example:
id: ebf0406a-5c70-4a04-8a29-25267c9d50bc
clientId: admin-cli
protocol: openid-connect
description: ''
baseUrl: /realms/master/account/
securitySchemes:
JWT:
type: apiKey
description: |
You can create a JSON Web Token (JWT) during auth.
Usage format: `Bearer <JWT>`
name: Authorization
in: header
tags:
-
name: master