Hiroyuki Wada
6 years ago
11 changed files with 462 additions and 0 deletions
-
4.gitignore
-
47ear/pom.xml
-
15ear/src/main/application/META-INF/jboss-deployment-structure.xml
-
52ejb/pom.xml
-
95ejb/src/main/java/org/keycloak/social/discord/DiscordIdentityProvider.java
-
46ejb/src/main/java/org/keycloak/social/discord/DiscordIdentityProviderFactory.java
-
6ejb/src/main/resources/META-INF/keycloak-themes.json
-
1ejb/src/main/resources/META-INF/services/org.keycloak.broker.social.SocialIdentityProviderFactory
-
127ejb/src/main/resources/theme/discord/admin/resources/partials/realm-identity-provider-discord.html
-
2ejb/src/main/resources/theme/discord/admin/theme.properties
-
67pom.xml
@ -0,0 +1,4 @@ |
|||||
|
target |
||||
|
.project |
||||
|
.classpath |
||||
|
.settings |
@ -0,0 +1,47 @@ |
|||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||
|
<parent> |
||||
|
<groupId>org.keycloak.extensions</groupId> |
||||
|
<artifactId>keycloak-discord-parent</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</parent> |
||||
|
|
||||
|
<name>Keycloak Discord EAR</name> |
||||
|
<description/> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>keycloak-discord-ear</artifactId> |
||||
|
<packaging>ear</packaging> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak.extensions</groupId> |
||||
|
<artifactId>keycloak-discord-ejb</artifactId> |
||||
|
<type>ejb</type> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<finalName>keycloak-discord</finalName> |
||||
|
|
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||
|
<artifactId>maven-ear-plugin</artifactId> |
||||
|
<version>2.10</version> |
||||
|
<configuration> |
||||
|
<version>7</version> |
||||
|
<defaultLibBundleDir>lib</defaultLibBundleDir> |
||||
|
<fileNameMapping>no-version</fileNameMapping> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
<plugin> |
||||
|
<groupId>org.wildfly.plugins</groupId> |
||||
|
<artifactId>wildfly-maven-plugin</artifactId> |
||||
|
<configuration> |
||||
|
<skip>false</skip> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</build> |
||||
|
</project> |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<jboss-deployment-structure> |
||||
|
<deployment> |
||||
|
<dependencies> |
||||
|
<module name="org.keycloak.keycloak-core" export="true" /> |
||||
|
<module name="org.keycloak.keycloak-server-spi" export="true" /> |
||||
|
<module name="org.keycloak.keycloak-server-spi-private" export="true" /> |
||||
|
<module name="org.keycloak.keycloak-services" export="true" /> |
||||
|
<module name="org.keycloak.keycloak-saml-core-public" export="true" /> |
||||
|
<module name="org.bouncycastle" export="true" /> |
||||
|
<module name="com.google.guava" export="true" /> |
||||
|
<module name="org.jboss.logging" export="true" /> |
||||
|
</dependencies> |
||||
|
</deployment> |
||||
|
</jboss-deployment-structure> |
@ -0,0 +1,52 @@ |
|||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||
|
<parent> |
||||
|
<groupId>org.keycloak.extensions</groupId> |
||||
|
<artifactId>keycloak-discord-parent</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
</parent> |
||||
|
|
||||
|
<name>Keycloak Discord EJB</name> |
||||
|
<description/> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<artifactId>keycloak-discord-ejb</artifactId> |
||||
|
<packaging>jar</packaging> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-core</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-server-spi</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-server-spi-private</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-services</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
<build> |
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||
|
<version>2.3.2</version> |
||||
|
<configuration> |
||||
|
<source>1.8</source> |
||||
|
<target>1.8</target> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</build> |
||||
|
</project> |
@ -0,0 +1,95 @@ |
|||||
|
/* |
||||
|
* Copyright 2018 Red Hat, Inc. and/or its affiliates |
||||
|
* and other contributors as indicated by the @author tags. |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
package org.keycloak.social.discord; |
||||
|
|
||||
|
import org.jboss.logging.Logger; |
||||
|
import org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider; |
||||
|
import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig; |
||||
|
import org.keycloak.broker.oidc.mappers.AbstractJsonUserAttributeMapper; |
||||
|
import org.keycloak.broker.provider.BrokeredIdentityContext; |
||||
|
import org.keycloak.broker.provider.IdentityBrokerException; |
||||
|
import org.keycloak.broker.provider.util.SimpleHttp; |
||||
|
import org.keycloak.broker.social.SocialIdentityProvider; |
||||
|
import org.keycloak.events.EventBuilder; |
||||
|
import org.keycloak.models.KeycloakSession; |
||||
|
import org.keycloak.social.linkedin.LinkedInIdentityProvider; |
||||
|
|
||||
|
import com.fasterxml.jackson.databind.JsonNode; |
||||
|
|
||||
|
/** |
||||
|
* @author <a href="mailto:wadahiro@gmail.com">Hiroyuki Wada</a> |
||||
|
*/ |
||||
|
public class DiscordIdentityProvider extends AbstractOAuth2IdentityProvider<OAuth2IdentityProviderConfig> |
||||
|
implements SocialIdentityProvider<OAuth2IdentityProviderConfig> { |
||||
|
|
||||
|
private static final Logger log = Logger.getLogger(LinkedInIdentityProvider.class); |
||||
|
|
||||
|
public static final String AUTH_URL = "https://discordapp.com/api/oauth2/authorize"; |
||||
|
public static final String TOKEN_URL = "https://discordapp.com/api/oauth2/token"; |
||||
|
public static final String PROFILE_URL = "https://discordapp.com/api/users/@me"; |
||||
|
public static final String DEFAULT_SCOPE = "identify email"; |
||||
|
|
||||
|
public DiscordIdentityProvider(KeycloakSession session, OAuth2IdentityProviderConfig config) { |
||||
|
super(session, config); |
||||
|
config.setAuthorizationUrl(AUTH_URL); |
||||
|
config.setTokenUrl(TOKEN_URL); |
||||
|
config.setUserInfoUrl(PROFILE_URL); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected boolean supportsExternalExchange() { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected String getProfileEndpointForValidation(EventBuilder event) { |
||||
|
return PROFILE_URL; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected BrokeredIdentityContext extractIdentityFromProfile(EventBuilder event, JsonNode profile) { |
||||
|
BrokeredIdentityContext user = new BrokeredIdentityContext(getJsonProperty(profile, "id")); |
||||
|
|
||||
|
user.setUsername(getJsonProperty(profile, "username")); |
||||
|
// user.setName(getJsonProperty(profile, "username")); |
||||
|
user.setEmail(getJsonProperty(profile, "email")); |
||||
|
user.setIdpConfig(getConfig()); |
||||
|
user.setIdp(this); |
||||
|
|
||||
|
AbstractJsonUserAttributeMapper.storeUserProfileForMapper(user, profile, getConfig().getAlias()); |
||||
|
|
||||
|
return user; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected BrokeredIdentityContext doGetFederatedIdentity(String accessToken) { |
||||
|
log.debug("doGetFederatedIdentity()"); |
||||
|
try { |
||||
|
JsonNode profile = SimpleHttp.doGet(PROFILE_URL, session).header("Authorization", "Bearer " + accessToken).asJson(); |
||||
|
// System.out.println(profile.toString()); |
||||
|
return extractIdentityFromProfile(null, profile); |
||||
|
} catch (Exception e) { |
||||
|
throw new IdentityBrokerException("Could not obtain user profile from discord.", e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected String getDefaultScopes() { |
||||
|
return DEFAULT_SCOPE; |
||||
|
} |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
/* |
||||
|
* Copyright 2018 Red Hat, Inc. and/or its affiliates |
||||
|
* and other contributors as indicated by the @author tags. |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
package org.keycloak.social.discord; |
||||
|
|
||||
|
import org.keycloak.broker.oidc.OIDCIdentityProviderConfig; |
||||
|
import org.keycloak.broker.provider.AbstractIdentityProviderFactory; |
||||
|
import org.keycloak.broker.social.SocialIdentityProviderFactory; |
||||
|
import org.keycloak.models.IdentityProviderModel; |
||||
|
import org.keycloak.models.KeycloakSession; |
||||
|
|
||||
|
/** |
||||
|
* @author <a href="mailto:wadahiro@gmail.com">Hiroyuki Wada</a> |
||||
|
*/ |
||||
|
public class DiscordIdentityProviderFactory extends AbstractIdentityProviderFactory<DiscordIdentityProvider> implements SocialIdentityProviderFactory<DiscordIdentityProvider> { |
||||
|
|
||||
|
public static final String PROVIDER_ID = "discord"; |
||||
|
|
||||
|
@Override |
||||
|
public String getName() { |
||||
|
return "Discord"; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public DiscordIdentityProvider create(KeycloakSession session, IdentityProviderModel model) { |
||||
|
return new DiscordIdentityProvider(session, new OIDCIdentityProviderConfig(model)); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getId() { |
||||
|
return PROVIDER_ID; |
||||
|
} |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
{ |
||||
|
"themes": [{ |
||||
|
"name" : "discord", |
||||
|
"types": [ "admin" ] |
||||
|
}] |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
org.keycloak.social.discord.DiscordIdentityProviderFactory |
@ -0,0 +1,127 @@ |
|||||
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2"> |
||||
|
<ol class="breadcrumb"> |
||||
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li> |
||||
|
<li data-ng-hide="newIdentityProvider">{{provider.name}}</li> |
||||
|
<li data-ng-show="newIdentityProvider">{{:: 'add-identity-provider' | translate}}</li> |
||||
|
</ol> |
||||
|
|
||||
|
<kc-tabs-identity-provider></kc-tabs-identity-provider> |
||||
|
|
||||
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageIdentityProviders"> |
||||
|
<fieldset> |
||||
|
<div class="form-group clearfix"> |
||||
|
<label class="col-md-2 control-label" for="redirectUri">{{:: 'redirect-uri' | translate}}</label> |
||||
|
<div class="col-sm-6"> |
||||
|
<input class="form-control" id="redirectUri" type="text" value="{{callbackUrl}}{{identityProvider.alias}}/endpoint" readonly kc-select-action="click"> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'redirect-uri.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
<fieldset> |
||||
|
<div class="form-group clearfix"> |
||||
|
<label class="col-md-2 control-label" for="clientId"><span class="required">*</span> {{:: 'discord-client-id' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input class="form-control" id="clientId" type="text" ng-model="identityProvider.config.clientId" required> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'discord.client-id.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group clearfix"> |
||||
|
<label class="col-md-2 control-label" for="clientSecret"><span class="required">*</span> {{:: 'discord-client-secret' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input class="form-control" id="clientSecret" kc-password ng-model="identityProvider.config.clientSecret" required> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'discord.client-secret.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group clearfix"> |
||||
|
<label class="col-md-2 control-label" for="defaultScope">{{:: 'default-scopes' | translate}} </label> |
||||
|
<div class="col-md-6"> |
||||
|
<input class="form-control" id="defaultScope" type="text" ng-model="identityProvider.config.defaultScope"> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'discord.default-scopes.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="enabled">{{:: 'store-tokens' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.storeToken" id="storeToken" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'identity-provider.store-tokens.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="storedTokensReadable">{{:: 'stored-tokens-readable' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.addReadTokenRoleOnCreate" id="storedTokensReadable" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'identity-provider.stored-tokens-readable.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.enabled" id="enabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'identity-provider.enabled.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="trustEmail">{{:: 'trust-email' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.trustEmail" name="identityProvider.trustEmail" id="trustEmail" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'trust-email.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="linkOnly">{{:: 'link-only' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.linkOnly" name="identityProvider.trustEmail" id="linkOnly" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'link-only.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="hideOnLoginPage">{{:: 'hide-on-login-page' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input ng-model="identityProvider.config.hideOnLoginPage" name="identityProvider.config.hideOnLoginPage" id="hideOnLoginPage" onoffswitchvalue on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}" /> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'hide-on-login-page.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="guiOrder">{{:: 'gui-order' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder"> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'gui-order.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="firstBrokerLoginFlowAlias">{{:: 'first-broker-login-flow' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<div> |
||||
|
<select class="form-control" id="firstBrokerLoginFlowAlias" |
||||
|
ng-model="identityProvider.firstBrokerLoginFlowAlias" |
||||
|
ng-options="flow.alias as flow.alias for flow in authFlows" |
||||
|
required> |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'first-broker-login-flow.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-2 control-label" for="postBrokerLoginFlowAlias">{{:: 'post-broker-login-flow' | translate}}</label> |
||||
|
<div class="col-md-6"> |
||||
|
<div> |
||||
|
<select class="form-control" id="postBrokerLoginFlowAlias" |
||||
|
ng-model="identityProvider.postBrokerLoginFlowAlias" |
||||
|
ng-options="flow.alias as flow.alias for flow in postBrokerAuthFlows"> |
||||
|
</select> |
||||
|
</div> |
||||
|
</div> |
||||
|
<kc-tooltip>{{:: 'post-broker-login-flow.tooltip' | translate}}</kc-tooltip> |
||||
|
</div> |
||||
|
</fieldset> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<div class="col-md-10 col-md-offset-2"> |
||||
|
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button> |
||||
|
<button kc-cancel data-ng-click="cancel()" data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</form> |
||||
|
</div> |
||||
|
|
||||
|
<kc-menu></kc-menu> |
@ -0,0 +1,2 @@ |
|||||
|
parent=keycloak |
||||
|
|
@ -0,0 +1,67 @@ |
|||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> |
||||
|
|
||||
|
<name>Keycloak Discord</name> |
||||
|
<description/> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>org.keycloak.extensions</groupId> |
||||
|
<artifactId>keycloak-discord-parent</artifactId> |
||||
|
<version>1.0.0-SNAPSHOT</version> |
||||
|
<packaging>pom</packaging> |
||||
|
|
||||
|
<properties> |
||||
|
<version.keycloak>4.5.0.Final</version.keycloak> |
||||
|
<version.wildfly.maven.plugin>1.1.0.Final</version.wildfly.maven.plugin> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencyManagement> |
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak.bom</groupId> |
||||
|
<artifactId>keycloak-spi-bom</artifactId> |
||||
|
<version>${version.keycloak}</version> |
||||
|
<type>pom</type> |
||||
|
<scope>import</scope> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak.extensions</groupId> |
||||
|
<artifactId>keycloak-discord-ejb</artifactId> |
||||
|
<version>${project.version}</version> |
||||
|
<type>ejb</type> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-server-spi-private</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
<version>${version.keycloak}</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.keycloak</groupId> |
||||
|
<artifactId>keycloak-services</artifactId> |
||||
|
<scope>provided</scope> |
||||
|
<version>${version.keycloak}</version> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
</dependencyManagement> |
||||
|
|
||||
|
<modules> |
||||
|
<module>ejb</module> |
||||
|
<module>ear</module> |
||||
|
</modules> |
||||
|
|
||||
|
<build> |
||||
|
<pluginManagement> |
||||
|
<plugins> |
||||
|
<plugin> |
||||
|
<groupId>org.wildfly.plugins</groupId> |
||||
|
<artifactId>wildfly-maven-plugin</artifactId> |
||||
|
<version>${version.wildfly.maven.plugin}</version> |
||||
|
<configuration> |
||||
|
<skip>true</skip> |
||||
|
</configuration> |
||||
|
</plugin> |
||||
|
</plugins> |
||||
|
</pluginManagement> |
||||
|
</build> |
||||
|
</project> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue