Skip to content

Commit

Permalink
Fixed init container (#2)
Browse files Browse the repository at this point in the history
* CI automation

* CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* [skip ci] CI automation

* CI/CD configured

* Added headless mode for automated tests

* fixed init container / added storing artifacts in github releases / other minor fixes

* release job fix

* [skip ci] release job fix

* release job fix2

* release job fix3

* release job fix4

* fixed AT
  • Loading branch information
kilmajster authored Jun 3, 2021
1 parent 3b8496e commit 672a0cd
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="debug-in-docker" type="Remote">
<module name="keycloak-user-attribute-authenticator" />
<module name="keycloak-username-password-attribute-authenticator" />
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" />
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/automation_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'

- name: Build authenticator jar file
run: mvn -B -ntp package
- name: Build test Docker container
run: docker build -f src/main/docker/dev.Dockerfile -t kilmajster/keycloak-with-authenticator:test .

- name: Build test docker container
run: docker-compose build

- name: Run Selenide tests
run: mvn -B -ntp test -P automation-tests
run: mvn -B -ntp test -P automation-tests -D headless=true
30 changes: 26 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
name: Publish package to the Maven Central Repository & Docker Hub

on:
release:
types: [created]

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Maven Central Repository
uses: actions/setup-java@v2
with:
Expand All @@ -15,16 +18,21 @@ jobs:
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
- name: Build project

- name: Build a project
run: mvn -B -ntp package

- name: Get the tag name
run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV

- name: Set version from git tag
run: mvn -B -ntp versions:set -DgenerateBackupPoms=false -DnewVersion="$TAG"
- name: Import gpg secret key

- name: Import GPG key
run: |
cat <(echo -e "${{ secrets.OSSRH_GPG_SECRET_KEY }}") | gpg --batch --import
gpg --list-secret-keys --keyid-format LONG
- name: Publish maven package
run: |
mvn \
Expand All @@ -36,19 +44,33 @@ jobs:
env:
MAVEN_USERNAME: kilmajster
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}

- name: Add jar to github release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/keycloak-username-password-attribute-authenticator-${{ env.TAG }}.jar
asset_name: keycloak-username-password-attribute-authenticator-${{ env.TAG }}.jar
tag: ${{ github.ref }}

- name: Build docker init container
run: |
echo "Building docker image = kilmajster/keycloak-username-password-attribute-authenticator:$TAG" && \
docker build \
--build-arg VERSION="$TAG" \
-f src/main/docker/initContainer.Dockerfile \
-t kilmajster/keycloak-username-password-attribute-authenticator:"$TAG" \
-t kilmajster/keycloak-username-password-attribute-authenticator:latest \
.
- name: Log into Docker Hub
uses: docker/login-action@v1
with:
username: kilmajster
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Push tagged image

- name: Push tagged docker image
run: docker push kilmajster/keycloak-username-password-attribute-authenticator:"$TAG"
- name: Push latest image

- name: Push latest docker image
run: docker push kilmajster/keycloak-username-password-attribute-authenticator:latest
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ hs_err_pid*
/build/
/keycloak-username-password-attribute-authenticator.iml
/.idea/
/target/
/target/
44 changes: 34 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
# keycloak-username-password-attribute-authenticator
# Keycloak username password attribute authenticator
[![CI with Selenide](https://github.com/kilmajster/keycloak-username-password-attribute-authenticator/actions/workflows/automation_tests.yml/badge.svg)](https://github.com/kilmajster/keycloak-username-password-attribute-authenticator/actions/workflows/automation_tests.yml)
![Maven Central](https://img.shields.io/maven-central/v/io.github.kilmajster/keycloak-username-password-attribute-authenticator)
![Docker Image Version (latest by date)](https://img.shields.io/docker/v/kilmajster/keycloak-username-password-attribute-authenticator?label=docker%20hub)
![Docker Pulls](https://img.shields.io/docker/pulls/kilmajster/keycloak-username-password-attribute-authenticator)
![GitHub](https://img.shields.io/github/license/kilmajster/keycloak-username-password-attribute-authenticator)

## Description
Keycloak default login form with user attribute validation.

## Using
## How 2 use
### using jar
### using docker init container
```
kilmajster/keycloak-username-password-attribute-authenticator:latest
```
#### example helm chart snippet

## Configuration
### Authenticator config
#### config via Keycloak UI
#### config via Keycloak UI / API
- login_form_user_attribute
- login_form_generate_label
- login_form_attribute_label
Expand All @@ -23,16 +32,31 @@ Keycloak default login form with user attribute validation.
#### Using bundled default keycloak theme
#### Extending own theme

## docker
### example in docker-compose
-------------------------------------
### Development
#### build the project
```shell
$ docker-compose up --build --force-recreate
$ mvn package
```
http://localhost:8081/auth/realms/dev-realm/account

#### run with docker-compose
```shell
$ docker-compose up --build
```
http://localhost:8081/auth/realms/dev-realm/account
##### debug in docker with IntelliJ
`.github/debug-in-docker.run.xml`

### init container
#### automation tests
##### build test docker image
```shell
$ docker-compose build
```
kilmajster/keycloak-username-password-attribute-authenticator:latest
##### running tests with chrome
```shell
$ mvn test -P automation-tests
```
##### running tests in docker
```shell
$ mvn test -P automation-tests -D headless=true
```

2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
- 8081:8080
- 8787:8787
volumes:
- ./src/main/resources/dev-realm.json:/tmp/dev-realm.json
- ./src/test/resources/dev-realm.json:/tmp/dev-realm.json
environment:
DEBUG: 'true'
DEBUG_PORT: '*:8787'
Expand Down
2 changes: 1 addition & 1 deletion src/main/docker/dev.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM quay.io/keycloak/keycloak:latest

ADD target/keycloak-username-password-attribute-authenticator-*.jar /opt/jboss/keycloak/standalone/deployments
ADD target/keycloak-username-password-attribute-authenticator-SNAPSHOT.jar /opt/jboss/keycloak/standalone/deployments
4 changes: 3 additions & 1 deletion src/main/docker/initContainer.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
FROM busybox

COPY target/keycloak-username-password-attribute-authenticator-*.jar /opt/jboss/keycloak/standalone/deployments/
ARG VERSION

COPY target/keycloak-username-password-attribute-authenticator-${VERSION}.jar /opt/jboss/keycloak/standalone/deployments/
7 changes: 4 additions & 3 deletions src/main/resources/theme/base-with-attribute/login/login.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@
<#else>
${msg("login_form_attribute_label_default")}
</#if>
</label>
</label>

<input tabindex="3" id="login_form_user_attribute" class="${properties.kcInputClass!}" name="login_form_user_attribute" type="text" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
<input tabindex="3" id="login_form_user_attribute" class="${properties.kcInputClass!}"
name="login_form_user_attribute" type="text" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('login_form_user_attribute')>true</#if>"
/>
</div>
<!-- keycloak-user-attribute-authenticator custom code block end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
package io.github.kilmajster.keycloak;


import com.codeborne.selenide.WebDriverRunner;
import dasniko.testcontainers.keycloak.KeycloakContainer;
import io.github.kilmajster.keycloak.base.BaseKeycloakInDockerAT;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.containers.BrowserWebDriverContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;

import static io.github.kilmajster.keycloak.base.Steps.*;
Expand All @@ -25,26 +19,11 @@ public class UsernamePasswordAttributeFormAT extends BaseKeycloakInDockerAT {
.withNetworkAliases(KEYCLOAK_NETWORK_ALIAS)
.withLogConsumer(new Slf4jLogConsumer(log));

@Rule
public BrowserWebDriverContainer chrome = (BrowserWebDriverContainer) new BrowserWebDriverContainer()
.withCapabilities(new ChromeOptions())
.withNetwork(testNetwork)
.withLogConsumer(new Slf4jLogConsumer(log));

@Before
public void setUp() {
RemoteWebDriver driver = chrome.getWebDriver();
WebDriverRunner.setWebDriver(driver);
}

@After
public void tearDown() {
WebDriverRunner.closeWebDriver();
}

@Test
public void shouldLogIntoAccountConsole() {
go_to_keycloak_account_page(KEYCLOAK_TEST_URL);
final String keycloakBaseUrl = getKeycloakBaseUrl(keycloak);

go_to_keycloak_account_page(keycloakBaseUrl);
click_sign_in_button();
verify_login_form_is_displayed_with_user_attribute_label("Test attr");
log_into_account_console();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package io.github.kilmajster.keycloak;

import com.codeborne.selenide.WebDriverRunner;
import dasniko.testcontainers.keycloak.KeycloakContainer;
import io.github.kilmajster.keycloak.base.BaseKeycloakInDockerAT;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testcontainers.containers.BrowserWebDriverContainer;
import org.testcontainers.containers.output.Slf4jLogConsumer;

import static io.github.kilmajster.keycloak.base.Steps.*;
Expand All @@ -25,26 +19,11 @@ public class UsernamePasswordAttributeFormEnvVarConfigAT extends BaseKeycloakInD
.withNetworkAliases(KEYCLOAK_NETWORK_ALIAS)
.withLogConsumer(new Slf4jLogConsumer(log));

@Rule
public BrowserWebDriverContainer chrome = (BrowserWebDriverContainer) new BrowserWebDriverContainer()
.withCapabilities(new ChromeOptions())
.withNetwork(testNetwork)
.withLogConsumer(new Slf4jLogConsumer(log));

@Before
public void setUp() {
RemoteWebDriver driver = chrome.getWebDriver();
WebDriverRunner.setWebDriver(driver);
}

@After
public void tearDown() {
WebDriverRunner.closeWebDriver();
}

@Test
public void shouldTakeAttributeLabelFromEnvVariable() {
go_to_keycloak_account_page(KEYCLOAK_TEST_URL);
final String keycloakBaseUrl = getKeycloakBaseUrl(keycloak);

go_to_keycloak_account_page(keycloakBaseUrl);
click_sign_in_button();
verify_login_form_is_displayed_with_user_attribute_label("Custom label");
log_into_account_console();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package io.github.kilmajster.keycloak.base;

import com.codeborne.selenide.WebDriverRunner;
import dasniko.testcontainers.keycloak.KeycloakContainer;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.BrowserWebDriverContainer;
import org.testcontainers.containers.Container;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.output.Slf4jLogConsumer;

public abstract class BaseKeycloakInDockerAT {

Expand All @@ -12,8 +21,39 @@ public abstract class BaseKeycloakInDockerAT {
protected static final String KEYCLOAK_DEV_DOCKER_IMAGE = "kilmajster/keycloak-with-authenticator:test";
protected static final String KEYCLOAK_NETWORK_ALIAS = "keycloak-host";
protected static final int KEYCLOAK_DEFAULT_PORT = 8080;
protected static final String KEYCLOAK_TEST_URL = "http://" + KEYCLOAK_NETWORK_ALIAS + ":" + KEYCLOAK_DEFAULT_PORT;
protected static final String KEYCLOAK_DOCKER_URL = "http://" + KEYCLOAK_NETWORK_ALIAS + ":" + KEYCLOAK_DEFAULT_PORT;
protected static final String KEYCLOAK_LOCAL_URL_PREFIX = "http://localhost:";

@Rule
public Network testNetwork = Network.newNetwork();
public Network testNetwork = isHeadless() ? Network.newNetwork() : null;

@Rule
public BrowserWebDriverContainer chrome = isHeadless() ? (BrowserWebDriverContainer) new BrowserWebDriverContainer()
.withCapabilities(new ChromeOptions())
.withNetwork(testNetwork)
.withLogConsumer(new Slf4jLogConsumer(log)) : null;

@Before
public void setUp() {
if (isHeadless()) {
log.info("Headless mode is enabled!");
RemoteWebDriver driver = chrome.getWebDriver();
WebDriverRunner.setWebDriver(driver);
}
}

@After
public void tearDown() {
if (isHeadless()) {
WebDriverRunner.closeWebDriver();
}
}

protected static boolean isHeadless() {
return Boolean.parseBoolean(System.getProperty("headless"));
}

protected String getKeycloakBaseUrl(final KeycloakContainer keycloakContainer) {
return isHeadless() ? KEYCLOAK_DOCKER_URL : KEYCLOAK_LOCAL_URL_PREFIX + keycloakContainer.getFirstMappedPort();
}
}
Loading

0 comments on commit 672a0cd

Please sign in to comment.