From 8626ac63b03e069a63069089db5a4427a7d81398 Mon Sep 17 00:00:00 2001 From: Julian Picht <julian.picht@gmail.com> Date: Fri, 13 Sep 2019 08:50:28 +0200 Subject: [PATCH] initial code --- Dockerfile | 4 + pom.xml | 72 ++++++++++++++++++ .../policy/GroupPasswordPolicyProvider.java | 75 +++++++++++++++++++ .../GroupPasswordPolicyProviderFactory.java | 73 ++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 Dockerfile create mode 100644 pom.xml create mode 100644 src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProvider.java create mode 100644 src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProviderFactory.java diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..beed755 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM docker.io/jboss/keycloak:6.0.1 +COPY target/keycloak-group-password-policy-0.1-SNAPSHOT.jar /opt/jboss/keycloak/standalone/deployments +RUN /opt/jboss/keycloak/bin/add-user-keycloak.sh -u admin -p admin +#RUN /opt/jboss/keycloak/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5675d22 --- /dev/null +++ b/pom.xml @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.github.jpicht.keycloak.policy</groupId> + <artifactId>keycloak-group-password-policy</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>jar</packaging> + + <properties> + <!-- general settings --> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <java.version>1.8</java.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + + <keycloak.version>6.0.1</keycloak.version> + <auto-service.version>1.0-rc5</auto-service.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-server-spi-private</artifactId> + <version>${keycloak.version}</version> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-server-spi</artifactId> + <version>${keycloak.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.logging</groupId> + <artifactId>jboss-logging</artifactId> + <version>3.4.0.Final</version> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-core</artifactId> + <version>${keycloak.version}</version> + </dependency> + <dependency> + <groupId>com.google.auto.service</groupId> + <artifactId>auto-service</artifactId> + <version>${auto-service.version}</version> + <scope>provided</scope> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.keycloak.testsuite</groupId> + <artifactId>integration-arquillian-tests-base</artifactId> + <version>6.0.1</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.keycloak</groupId> + <artifactId>keycloak-test-helper</artifactId> + <version>6.0.1</version> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>3.1.1</version> + </plugin> + </plugins> + </pluginManagement> + </build> +</project> diff --git a/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProvider.java b/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProvider.java new file mode 100644 index 0000000..9b19493 --- /dev/null +++ b/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProvider.java @@ -0,0 +1,75 @@ +package com.github.jpicht.keycloak.policy; + +/* + * Copyright 2019 Julian Picht + * + * 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. + */ + +import java.util.List; +import org.keycloak.models.GroupModel; +import org.keycloak.models.KeycloakContext; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.policy.PasswordPolicyConfigException; +import org.keycloak.policy.PasswordPolicyProvider; +import org.keycloak.policy.PolicyError; +import org.jboss.logging.Logger; + +public class GroupPasswordPolicyProvider implements PasswordPolicyProvider { + + private static final Logger logger = Logger.getLogger(GroupPasswordPolicyProvider.class); + private static final String ERROR_MESSAGE = "invalidGroupPasswordPolicy"; + + private KeycloakContext context; + + public GroupPasswordPolicyProvider(KeycloakContext context) { + this.context = context; + } + + @Override + public PolicyError validate(String username, String password) { + return null; + } + + @Override + public PolicyError validate(RealmModel realm, UserModel user, String password) { + String groupAttribute = context.getRealm().getPasswordPolicy().getPolicyConfig(GroupPasswordPolicyProviderFactory.ID); + logger.infof("groupAttribute %s", groupAttribute); + logger.infof("user %s", user.getUsername()); + for (GroupModel group : user.getGroups()) { + logger.infof("group %s", group.getName()); + for (String policy : group.getAttribute(groupAttribute)) { + //factorPolicy(policy).validate(); + logger.info(policy); + } + } + realm.getPasswordPolicy(); + logger.infof("account theme ", context.getRealm().getAccountTheme()); + logger.infof("admin theme ", context.getRealm().getAdminTheme()); + logger.infof("login theme ", context.getRealm().getLoginTheme()); + return new PolicyError("nope"); + } + + @Override + public Object parseConfig(String value) { + if (value == null || value.isEmpty()) { + throw new PasswordPolicyConfigException("Attribute name cannot be blank"); + } + return value; + } + + @Override + public void close() { + } +} diff --git a/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProviderFactory.java b/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProviderFactory.java new file mode 100644 index 0000000..31106b8 --- /dev/null +++ b/src/main/java/com/github/jpicht/keycloak/policy/GroupPasswordPolicyProviderFactory.java @@ -0,0 +1,73 @@ +package com.github.jpicht.keycloak.policy; + + +/* + * Copyright 2019 Julian Picht + * + * 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. + */ + +import com.google.auto.service.AutoService; +import org.keycloak.Config; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.policy.PasswordPolicyProvider; +import org.keycloak.policy.PasswordPolicyProviderFactory; + +@AutoService(PasswordPolicyProviderFactory.class) +public class GroupPasswordPolicyProviderFactory implements PasswordPolicyProviderFactory { + + static final String ID = "groupPasswordPolicy"; + + @Override + public String getId() { + return ID; + } + + @Override + public PasswordPolicyProvider create(KeycloakSession session) { + return new GroupPasswordPolicyProvider(session.getContext()); + } + + @Override + public void init(Config.Scope config) { + } + + @Override + public void postInit(KeycloakSessionFactory factory) { + } + + @Override + public String getDisplayName() { + return "Group Policy"; + } + + @Override + public String getConfigType() { + return PasswordPolicyProvider.STRING_CONFIG_TYPE; + } + + @Override + public String getDefaultConfigValue() { + return ""; + } + + @Override + public boolean isMultiplSupported() { + return true; + } + + @Override + public void close() { + } +}