From 3e3e96905975adedd6793e1ec6b899c9f8dad25f Mon Sep 17 00:00:00 2001
From: Bartu <Bartu@DESKTOP-I65UMOO.mshome.net>
Date: Tue, 25 Jan 2022 20:38:36 +0100
Subject: [PATCH] initial commit

---
 .classpath                                    |  38 ++++++
 .project                                      |  23 ++++
 .settings/org.eclipse.core.resources.prefs    |   2 +
 .settings/org.eclipse.jdt.core.prefs          |   8 ++
 .settings/org.eclipse.m2e.core.prefs          |   4 +
 choose-initial/.classpath                     |  38 ++++++
 choose-initial/.project                       |  23 ++++
 .../org.eclipse.core.resources.prefs          |   6 +
 .../.settings/org.eclipse.jdt.core.prefs      |   8 ++
 .../.settings/org.eclipse.m2e.core.prefs      |   4 +
 .../org.jboss.ide.eclipse.as.core.prefs       |   2 +
 choose-initial/pom.xml                        |  81 ++++++++++++
 .../ChooseInitialRequiredAction.java          | 121 ++++++++++++++++++
 .../ChooseInitialRequiredActionFactory.java   |  61 +++++++++
 ...cloak.authentication.RequiredActionFactory |  18 +++
 .../templates/choose-initial.ftl              |  45 +++++++
 ...-initial-authenticator-required-action.jar | Bin 0 -> 8613 bytes
 ...cloak.authentication.RequiredActionFactory |  18 +++
 .../ChooseInitialRequiredAction.class         | Bin 0 -> 8062 bytes
 .../ChooseInitialRequiredActionFactory.class  | Bin 0 -> 1816 bytes
 .../templates/choose-initial.ftl              |  45 +++++++
 .../target/maven-archiver/pom.properties      |   5 +
 .../compile/default-compile/createdFiles.lst  |   2 +
 .../compile/default-compile/inputFiles.lst    |   2 +
 .../default-testCompile/inputFiles.lst        |   0
 pom.xml                                       |  33 +++++
 26 files changed, 587 insertions(+)
 create mode 100644 .classpath
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.core.resources.prefs
 create mode 100644 .settings/org.eclipse.jdt.core.prefs
 create mode 100644 .settings/org.eclipse.m2e.core.prefs
 create mode 100644 choose-initial/.classpath
 create mode 100644 choose-initial/.project
 create mode 100644 choose-initial/.settings/org.eclipse.core.resources.prefs
 create mode 100644 choose-initial/.settings/org.eclipse.jdt.core.prefs
 create mode 100644 choose-initial/.settings/org.eclipse.m2e.core.prefs
 create mode 100644 choose-initial/.settings/org.jboss.ide.eclipse.as.core.prefs
 create mode 100644 choose-initial/pom.xml
 create mode 100644 choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.java
 create mode 100644 choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.java
 create mode 100644 choose-initial/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory
 create mode 100644 choose-initial/src/main/resources/theme-resources/templates/choose-initial.ftl
 create mode 100644 choose-initial/target/choose-initial-authenticator-required-action.jar
 create mode 100644 choose-initial/target/classes/META-INF/services/org.keycloak.authentication.RequiredActionFactory
 create mode 100644 choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.class
 create mode 100644 choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.class
 create mode 100644 choose-initial/target/classes/theme-resources/templates/choose-initial.ftl
 create mode 100644 choose-initial/target/maven-archiver/pom.properties
 create mode 100644 choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
 create mode 100644 choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
 create mode 100644 choose-initial/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
 create mode 100644 pom.xml

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..90f81ed
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..5b9275b
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>bartuli-project</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..5723a0f
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.5
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/choose-initial/.classpath b/choose-initial/.classpath
new file mode 100644
index 0000000..0fb79cf
--- /dev/null
+++ b/choose-initial/.classpath
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/choose-initial/.project b/choose-initial/.project
new file mode 100644
index 0000000..cda0897
--- /dev/null
+++ b/choose-initial/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>choose-initial</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+</projectDescription>
diff --git a/choose-initial/.settings/org.eclipse.core.resources.prefs b/choose-initial/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..29abf99
--- /dev/null
+++ b/choose-initial/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,6 @@
+eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/main/resources=UTF-8
+encoding//src/test/java=UTF-8
+encoding//src/test/resources=UTF-8
+encoding/<project>=UTF-8
diff --git a/choose-initial/.settings/org.eclipse.jdt.core.prefs b/choose-initial/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..2af1e7b
--- /dev/null
+++ b/choose-initial/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/choose-initial/.settings/org.eclipse.m2e.core.prefs b/choose-initial/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/choose-initial/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/choose-initial/.settings/org.jboss.ide.eclipse.as.core.prefs b/choose-initial/.settings/org.jboss.ide.eclipse.as.core.prefs
new file mode 100644
index 0000000..cf3aa3a
--- /dev/null
+++ b/choose-initial/.settings/org.jboss.ide.eclipse.as.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.jboss.ide.eclipse.as.core.singledeployable.deployableList=
diff --git a/choose-initial/pom.xml b/choose-initial/pom.xml
new file mode 100644
index 0000000..33909c1
--- /dev/null
+++ b/choose-initial/pom.xml
@@ -0,0 +1,81 @@
+<!--
+  ~ Copyright 2016 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.
+  -->
+
+<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>
+        <artifactId>bartuli-project</artifactId>
+        <groupId>de.puzzle-itc.keycloak</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <name>Choose Initial Authenticator Required Action</name>
+    <description/>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>choose-initial</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <scope>provided</scope>
+            <version>${keycloak.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-spi</artifactId>
+            <scope>provided</scope>
+            <version>${keycloak.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-server-spi-private</artifactId>
+            <scope>provided</scope>
+            <version>${keycloak.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+            <scope>provided</scope>
+            <version>3.4.1.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-services</artifactId>
+            <scope>provided</scope>
+            <version>${keycloak.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>choose-initial-authenticator-required-action</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven-surefire-plugin.version}</version>
+                <configuration>
+                    <excludes>
+                        <exclude>**/*IntegrationTest.java</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.java b/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.java
new file mode 100644
index 0000000..5b89371
--- /dev/null
+++ b/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016 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 de.puzzleitc.keycloak.auth.requiredactions;
+
+import org.keycloak.authentication.RequiredActionContext;
+import org.keycloak.authentication.RequiredActionProvider;
+import org.keycloak.credential.CredentialProvider;
+import org.keycloak.credential.CredentialTypeMetadata;
+import org.keycloak.credential.CredentialTypeMetadataContext;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.ws.rs.core.Response;
+
+/**
+ * Wenn der User einen Authenticator der Kategorie TWO-FACTOR bereits
+ * konfiguriert hat kann die required action direkt als abgeschlossen gesetzt
+ * und verlassen werden, sonst wird das Formular zur Auswahl erzeugt und die
+ * challenge Response an den User weitergeben.
+ * 
+ * @author Alexander Bartuli
+ */
+public class ChooseInitialRequiredAction implements RequiredActionProvider {
+
+	public static final String PROVIDER_ID = "choose_initial_required_action";
+
+	@Override
+	public void evaluateTriggers(RequiredActionContext context) {
+
+	}
+
+	@Override
+	public void requiredActionChallenge(RequiredActionContext context) {
+
+		KeycloakSession session = context.getSession();
+		RealmModel realm = context.getRealm();
+		UserModel user = context.getUser();
+
+		// Ein Stream Supplier für CredentialProvider der Category TWO-FACTOR
+		Supplier<Stream<CredentialProvider>> twoFactorProvidersSupplier = () -> session.getKeycloakSessionFactory()
+				.getProviderFactoriesStream(CredentialProvider.class)
+				.map(providerFactory -> session.getProvider(CredentialProvider.class, providerFactory.getId()))
+				.filter(provider -> Objects.equals(
+						provider.getCredentialTypeMetadata(CredentialTypeMetadataContext.builder().build(session))
+								.getCategory(),
+						CredentialTypeMetadata.Category.TWO_FACTOR));
+
+		// Ein Boolean, der true ist, sobald ein CredentialProvider der Kategorie
+		// TWO-FACTOR für den User konfiguriert ist
+		boolean hasTwoFactorCategoryConfigured = twoFactorProvidersSupplier.get()
+				.anyMatch(provider -> session.userCredentialManager().isConfiguredFor(realm, user, provider.getType()));
+
+		// Eine Liste aller CredentialTypeMetadata der CredentialProvider der Kategorie
+		// TWO-FACTOR
+		List<CredentialTypeMetadata> twoFactorProviderCredentialTypeMetadata = twoFactorProvidersSupplier.get().map(
+				provider -> provider.getCredentialTypeMetadata(CredentialTypeMetadataContext.builder().build(session)))
+				.collect(Collectors.toList());
+
+		if (hasTwoFactorCategoryConfigured) {
+
+			context.success();
+
+		} else {
+
+			Response challenge = context.form().setAttribute("twoFactors", twoFactorProviderCredentialTypeMetadata)
+					.createForm("choose-initial.ftl");
+			context.challenge(challenge);
+
+		}
+	}
+
+	@Override
+	public void processAction(RequiredActionContext context) {
+		UserModel user = context.getUser();
+		String choosenProviderId = (context.getHttpRequest().getDecodedFormParameters().getFirst("choosenProviderId"));
+
+//    	user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
+//    	user.removeRequiredAction("webauthn-register");
+
+		if (choosenProviderId != null) {
+			
+			user.addRequiredAction(choosenProviderId);
+			
+		} else {
+			
+			Response challenge = context.form().setError("No Option Selected").createForm("choose-initial.ftl");
+			context.challenge(challenge);
+			return;
+			
+		}
+		
+		context.success();
+	}
+
+	@Override
+	public void close() {
+
+	}
+}
diff --git a/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.java b/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.java
new file mode 100644
index 0000000..eeef2fc
--- /dev/null
+++ b/choose-initial/src/main/java/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 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 de.puzzleitc.keycloak.auth.requiredactions;
+
+import org.keycloak.Config;
+import org.keycloak.authentication.RequiredActionFactory;
+import org.keycloak.authentication.RequiredActionProvider;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+
+public class ChooseInitialRequiredActionFactory implements RequiredActionFactory {
+
+    private static final ChooseInitialRequiredAction SINGLETON = new ChooseInitialRequiredAction();
+
+    @Override
+    public RequiredActionProvider create(KeycloakSession session) {
+        return SINGLETON;
+    }
+
+    @Override
+    public String getId() {
+        return ChooseInitialRequiredAction.PROVIDER_ID;
+    }
+
+    @Override
+    public String getDisplayText() {
+        return "Choose Initial 2FA Authenticator";
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+    	
+    }
+
+    @Override
+    public void close() {
+    	
+    }
+
+}
diff --git a/choose-initial/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory b/choose-initial/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory
new file mode 100644
index 0000000..a010974
--- /dev/null
+++ b/choose-initial/src/main/resources/META-INF/services/org.keycloak.authentication.RequiredActionFactory
@@ -0,0 +1,18 @@
+#
+# Copyright 2016 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.
+#
+
+de.puzzleitc.keycloak.auth.requiredactions.ChooseInitialRequiredActionFactory
\ No newline at end of file
diff --git a/choose-initial/src/main/resources/theme-resources/templates/choose-initial.ftl b/choose-initial/src/main/resources/theme-resources/templates/choose-initial.ftl
new file mode 100644
index 0000000..e14a195
--- /dev/null
+++ b/choose-initial/src/main/resources/theme-resources/templates/choose-initial.ftl
@@ -0,0 +1,45 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout displayInfo=true; section>
+    <#if section = "header" || section = "show-username">
+        <script type="text/javascript">
+            function fillAndSubmit(choosenProviderId) {
+                document.getElementById('choosenProvider').value = choosenProviderId;
+                document.getElementById('kc-select-credential-form').submit();
+            }
+        </script>
+        <#if section = "header">
+            SELECT AUTHENTICATOR TO SETUP
+        </#if>
+    <#elseif section = "form">
+        <form id="kc-select-credential-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
+        
+            <div class="${properties.kcSelectAuthListClass!}">
+            
+                <#list twoFactors as twoFactor>
+                    <div class="${properties.kcSelectAuthListItemClass!}" onclick="fillAndSubmit('${twoFactor.createAction}')">
+
+                        <div class="${properties.kcSelectAuthListItemIconClass!}">
+                            <i class="${properties['${twoFactor.iconCssClass}']!authenticationSelection.iconCssClass} fa-2x"></i>
+                        </div>
+                        <div class="${properties.kcSelectAuthListItemBodyClass!}">
+                            <div class="${properties.kcSelectAuthListItemHeadingClass!}">
+                                ${msg('${twoFactor.displayName}')}
+                            </div>
+                            <div class="${properties.kcSelectAuthListItemDescriptionClass!}">
+                                ${msg('${twoFactor.helpText}')}
+                            </div>
+                        </div>
+                        <div class="${properties.kcSelectAuthListItemFillClass!}"></div>
+                        <div class="${properties.kcSelectAuthListItemArrowClass!}">
+                            <i class="${properties.kcSelectAuthListItemArrowIconClass!}"></i>
+                        </div>
+                    </div>
+                </#list>
+                
+                <input type="hidden" id="choosenProvider" name="choosenProviderId" />
+                
+            </div>
+            
+        </form>
+    </#if>
+</@layout.registrationLayout>
\ No newline at end of file
diff --git a/choose-initial/target/choose-initial-authenticator-required-action.jar b/choose-initial/target/choose-initial-authenticator-required-action.jar
new file mode 100644
index 0000000000000000000000000000000000000000..2a7e409f7349e4a4573aa3afe34a8f21ac5883d5
GIT binary patch
literal 8613
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
Vr36Aoxl~F3dojU!R)2ZC{{tQ0+xP$g

literal 0
HcmV?d00001

diff --git a/choose-initial/target/classes/META-INF/services/org.keycloak.authentication.RequiredActionFactory b/choose-initial/target/classes/META-INF/services/org.keycloak.authentication.RequiredActionFactory
new file mode 100644
index 0000000..a010974
--- /dev/null
+++ b/choose-initial/target/classes/META-INF/services/org.keycloak.authentication.RequiredActionFactory
@@ -0,0 +1,18 @@
+#
+# Copyright 2016 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.
+#
+
+de.puzzleitc.keycloak.auth.requiredactions.ChooseInitialRequiredActionFactory
\ No newline at end of file
diff --git a/choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.class b/choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredAction.class
new file mode 100644
index 0000000000000000000000000000000000000000..d34df1546832523259a85deeea6c72aae27aca4a
GIT binary patch
literal 8062
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
H+i>iES8atQ

literal 0
HcmV?d00001

diff --git a/choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.class b/choose-initial/target/classes/de/puzzleitc/keycloak/auth/requiredactions/ChooseInitialRequiredActionFactory.class
new file mode 100644
index 0000000000000000000000000000000000000000..fae5751535270b43042645abd5eb3ff80e00a2e0
GIT binary patch
literal 1816
zcmb_cZBNrs6n^eD+HFig-V_iV^0qOcfC45XCd+iVIKenVV*Ef#cNvA!&bA}Mukt04
zL=%62KgxJ+S74n3{lJIz_TGD5p65B|^w;n2KLM;^Eshv6F+?#ZV?K(7D3mzu7UKvb
zBV$R%vW&+Jv2t;9qx52XYm?z+slt_7{p`%(x~nNi{8Te6^+-|c?tx<S4|Uz<6;*R}
z%XF0dfn_<oXzH%68gKo}oOhXJkk)m&dBzY<rFR%2d8@)1x=XsrH|xiH+}>9A3_9s8
zS(<9>sJ1Tl{$a#D&>e=YTY^&{$d-L7P-!+-T}t~tRkG~r6~kkKXE@3$pK+Nx4w1~J
zgH}QZZo0ar3JH`T={L4@qF1<0X=JD2&oC7Xa7`M9jw*MH6^8y)x^$?XsEVPQRi*6O
zx>==wU3C3icWQ=uy3Iejq^D3<#tM0sHLFI95=GPGcHU4OO3pCWLNITc`+9ZKGtP>N
zNSb%TFcO3qFl30<EXNf^W>8u}wkLBTw#XsxH<V|X3nsbQl}J(FIYesXzf!iAspeNg
zX(~x{T{HZSjF+vtt?_~``fuijHukA3h=L?=2VDttBEe9&ohhLrY2FO&3ScxuyB8z2
z+n6ziWCLAN6o3qp%Y|Grch!WJoj^YZ7+&8FBA+lr&s7g@?HzKBs=pMNmm4R+4<loh
zVJP6%+*}NOZSF8mKdBfP;`9s)z3F!*_9Q>OyJ@G;%4qGFJqP<tA0hP6Tk;M^aF@Ol
z4FmL|k9IUx7@)UseoAYI*2ouxKGE9jJMQ@oHtv02vcw?nkr%^#4Ea&!y*&`_jkE@t
zZUPX#1TfsjwWHNF)7Eta5B;nw9$w<pN_wdYIQ>#R(t>u9)D*xUVd7sQR<8*$i779{
z^rie6LLub;3q`gGzK^0ON7B#uxfe-TA-y!4`39+#d~@L>pF<R>%d``oFVOh|;dked
gzak`Lpk5UrJw&5qlBQh<vlydQw9o@Q!Kf7b19n-lKmY&$

literal 0
HcmV?d00001

diff --git a/choose-initial/target/classes/theme-resources/templates/choose-initial.ftl b/choose-initial/target/classes/theme-resources/templates/choose-initial.ftl
new file mode 100644
index 0000000..e14a195
--- /dev/null
+++ b/choose-initial/target/classes/theme-resources/templates/choose-initial.ftl
@@ -0,0 +1,45 @@
+<#import "template.ftl" as layout>
+<@layout.registrationLayout displayInfo=true; section>
+    <#if section = "header" || section = "show-username">
+        <script type="text/javascript">
+            function fillAndSubmit(choosenProviderId) {
+                document.getElementById('choosenProvider').value = choosenProviderId;
+                document.getElementById('kc-select-credential-form').submit();
+            }
+        </script>
+        <#if section = "header">
+            SELECT AUTHENTICATOR TO SETUP
+        </#if>
+    <#elseif section = "form">
+        <form id="kc-select-credential-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
+        
+            <div class="${properties.kcSelectAuthListClass!}">
+            
+                <#list twoFactors as twoFactor>
+                    <div class="${properties.kcSelectAuthListItemClass!}" onclick="fillAndSubmit('${twoFactor.createAction}')">
+
+                        <div class="${properties.kcSelectAuthListItemIconClass!}">
+                            <i class="${properties['${twoFactor.iconCssClass}']!authenticationSelection.iconCssClass} fa-2x"></i>
+                        </div>
+                        <div class="${properties.kcSelectAuthListItemBodyClass!}">
+                            <div class="${properties.kcSelectAuthListItemHeadingClass!}">
+                                ${msg('${twoFactor.displayName}')}
+                            </div>
+                            <div class="${properties.kcSelectAuthListItemDescriptionClass!}">
+                                ${msg('${twoFactor.helpText}')}
+                            </div>
+                        </div>
+                        <div class="${properties.kcSelectAuthListItemFillClass!}"></div>
+                        <div class="${properties.kcSelectAuthListItemArrowClass!}">
+                            <i class="${properties.kcSelectAuthListItemArrowIconClass!}"></i>
+                        </div>
+                    </div>
+                </#list>
+                
+                <input type="hidden" id="choosenProvider" name="choosenProviderId" />
+                
+            </div>
+            
+        </form>
+    </#if>
+</@layout.registrationLayout>
\ No newline at end of file
diff --git a/choose-initial/target/maven-archiver/pom.properties b/choose-initial/target/maven-archiver/pom.properties
new file mode 100644
index 0000000..60c4188
--- /dev/null
+++ b/choose-initial/target/maven-archiver/pom.properties
@@ -0,0 +1,5 @@
+#Generated by Maven
+#Tue Jan 25 20:35:49 CET 2022
+groupId=de.puzzle-itc.keycloak
+artifactId=choose-initial
+version=0.0.1-SNAPSHOT
diff --git a/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
new file mode 100644
index 0000000..24dacc1
--- /dev/null
+++ b/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
@@ -0,0 +1,2 @@
+de\puzzleitc\keycloak\auth\requiredactions\ChooseInitialRequiredAction.class
+de\puzzleitc\keycloak\auth\requiredactions\ChooseInitialRequiredActionFactory.class
diff --git a/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
new file mode 100644
index 0000000..d65d1ac
--- /dev/null
+++ b/choose-initial/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
@@ -0,0 +1,2 @@
+C:\Users\Bartu\git\choose-initial\choose-initial\src\main\java\de\puzzleitc\keycloak\auth\requiredactions\ChooseInitialRequiredActionFactory.java
+C:\Users\Bartu\git\choose-initial\choose-initial\src\main\java\de\puzzleitc\keycloak\auth\requiredactions\ChooseInitialRequiredAction.java
diff --git a/choose-initial/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/choose-initial/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst
new file mode 100644
index 0000000..e69de29
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2d4376c
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,33 @@
+<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>de.puzzle-itc.keycloak</groupId>
+	<artifactId>bartuli-project</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>auswahl</name>
+	<packaging>pom</packaging>
+
+	<modules>
+		<module>extensions</module>
+		<module>secret-question</module>
+		<module>ChooseInitial</module>
+		<module>choose-initial</module>
+	</modules>
+
+	<properties>
+		<!-- general settings -->
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<java.version>11</java.version>
+		<maven.compiler.source>${java.version}</maven.compiler.source>
+		<maven.compiler.target>${java.version}</maven.compiler.target>
+
+		<keycloak.version>16.1.0</keycloak.version>
+
+		<!-- Tooling -->
+		<auto-service.version>1.0.1</auto-service.version>
+		<lombok.version>1.18.22</lombok.version>
+		<docker-maven-plugin.version>0.36.1</docker-maven-plugin.version>
+		<maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
+		<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
+	</properties>
+</project>
\ No newline at end of file
-- 
GitLab