Skip to content
Snippets Groups Projects
Commit 3ba85115 authored by OZGCloud's avatar OZGCloud
Browse files

Merge branch 'master' into new-build-agent

parents 64110746 d2edd1f5
Branches
Tags
No related merge requests found
Showing
with 233 additions and 62 deletions
...@@ -6,7 +6,7 @@ pipeline { ...@@ -6,7 +6,7 @@ pipeline {
} }
environment { environment {
BLUE_OCEAN_URL = "https://jenkins.ozg-sh.de/job/user-manager/job/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/" BLUE_OCEAN_URL = "https://jenkins.infra.ozg-cloud.systems/job/user-manager/job/${env.BRANCH_NAME}/${env.BUILD_NUMBER}/"
RELEASE_REGEX = /\d+.\d+.\d+/ RELEASE_REGEX = /\d+.\d+.\d+/
SNAPSHOT_REGEX = /\d+.\d+.\d+-SNAPSHOT/ SNAPSHOT_REGEX = /\d+.\d+.\d+-SNAPSHOT/
FAILED_STAGE = "" FAILED_STAGE = ""
...@@ -200,6 +200,44 @@ pipeline { ...@@ -200,6 +200,44 @@ pipeline {
} }
} }
} }
stage('march build image') {
when {
branch 'master'
}
steps {
script {
FAILED_STAGE=env.STAGE_NAME
withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh './mvnw -pl user-manager-server -s $MAVEN_SETTINGS clean verify \
-Pnative -Dquarkus.container-image.registry=docker.ozg-sh.de \
-Dquarkus.container-image.username=${USER} \
-Dquarkus.container-image.password=${PASSWORD} \
-Dquarkus.container-image.push=true \
-Dquarkus.container-image.build=true \
-Dquarkus.native.remote-container-build=true \
-Dquarkus.native.additional-build-args=-march=compatibility \
-Dmaven.wagon.http.retryHandler.count=3'
}
}
}
}
}
stage('march push image') {
when {
branch 'master'
}
steps {
script {
FAILED_STAGE = env.STAGE_NAME
tagAndPushDockerImage('march-snapshot-latest')
}
}
}
} }
post { post {
......
# user-manager Project # user-manager
This project uses Quarkus, the Supersonic Subatomic Java Framework. This project uses Quarkus, the Supersonic Subatomic Java Framework.
...@@ -8,11 +8,11 @@ If you want to learn more about Quarkus, please visit its website: https://quark ...@@ -8,11 +8,11 @@ If you want to learn more about Quarkus, please visit its website: https://quark
This properties must be configured to run the application This properties must be configured to run the application
| Key | Value | Default | Mandatory | Description | | Key | Value | Default | Mandatory | Description |
| --- | ----- | ------- | --------- | ----------- | |-----------------------------------------------|----------------------------------------------------|------------------------| --------- |----------------------------------------------------------------|
| quarkus.oidc.auth-server-url | https://sso.dev.by.ozg-cloud.de/realms/sh-kiel-dev | none | yes | Url of the keycloak server with the realm | | quarkus.oidc.auth-server-url | https://sso.dev.by.ozg-cloud.de/realms/sh-kiel-dev | none | yes | Url of the keycloak server with the realm |
| quarkus.mongodb.connection-string | mongodb://ozg-mongodb:27017 | none | yes | The connection string for the mongo db database | | quarkus.mongodb.connection-string | mongodb://ozg-mongodb:27017 | none | yes | The connection string for the mongo db database |
| quarkus.mongodb.database | usermanager | usermanager | no | Name of the mongo db database | | quarkus.mongodb.database | usermanager | usermanager | no | Name of the mongo db database |
| kop.keycloak.sync.cron | 0 15 2 * * ? | 0 15 2 * * ? | no | Cron statement when the sync is done | | kop.keycloak.sync.period | 5m | 6h | no | Period between synchronizations |
| kop.keycloak.api.user | apiUser | none | yes | The name of the keycloak admin api user | | kop.keycloak.api.user | apiUser | none | yes | The name of the keycloak admin api user |
| kop.keycloak.api.password | **** | none | yes | The password of the keycloak admin api user | | kop.keycloak.api.password | **** | none | yes | The password of the keycloak admin api user |
| kop.keycloak.api.realm | realm-name | none | yes | The name of the realm | | kop.keycloak.api.realm | realm-name | none | yes | The name of the realm |
...@@ -30,6 +30,27 @@ You can run your application in dev mode that enables live coding using: ...@@ -30,6 +30,27 @@ You can run your application in dev mode that enables live coding using:
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/. > **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
> If you want to use remote Keycloak for local development, then use the profile remotekc. Be aware,
> that it deactivates synchronization - if you need it, then you have to create your own realm and
> set it in properties, like this:
> ```yaml
> keycloak:
> realm: your-realm
> ozgcloud:
> usersync:
> period: "6h"
> ```
## Running the server with custom realm
In order to start user-manager-server connecting againts dev keycloak locally with custom realm
use below configuration in your IDE or CLI.
```
-Dquarkus.profile=local,remotekc
-Dquarkus.oidc.auth-server-url=https://sso.dev.by.ozg-cloud.de/realms/sebo-test
-Dkop.keycloak.api.realm=sebo-test
-Dozgcloud.usersync.period="5s"
```
## Packaging and running the application ## Packaging and running the application
The application can be packaged using: The application can be packaged using:
...@@ -121,7 +142,7 @@ Usermanager als native Anwendung erstellen und lokal starten: ...@@ -121,7 +142,7 @@ Usermanager als native Anwendung erstellen und lokal starten:
-Dkop.keycloak.api.password=hlc_j1I1Ji0trC0 \ -Dkop.keycloak.api.password=hlc_j1I1Ji0trC0 \
-Dkop.keycloak.api.realm=by-kiel-dev \ -Dkop.keycloak.api.realm=by-kiel-dev \
-Dkop.keycloak.api.client=alfa \ -Dkop.keycloak.api.client=alfa \
-Dkop.keycloak.sync.cron="* */3 * * * ?" \ -Dozgcloud.usersync.period="5m" \
-Xmx32m -Xmx32m
``` ```
......
#!/usr/bin/env bash
export QUARKUS_CONTAINER_IMAGE_NAME=user-manager
export QUARKUS_CONTAINER_IMAGE_TAG=build-latest
export QUARKUS_NATIVE_CONTAINER_RUNTIME=docker
cd user-manager-server
./mvnw clean install -D skipTests \
-Pnative \
-Dquarkus.container-image.registry=docker.ozg-sh.de \
-Dquarkus.container-image.push=false \
-Dquarkus.container-image.build=true \
-Dquarkus.native.remote-container-build=false
\ No newline at end of file
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.itvsh.kop</groupId> <groupId>de.itvsh.kop</groupId>
<artifactId>user-manager</artifactId> <artifactId>user-manager</artifactId>
<version>1.13.0-SNAPSHOT</version> <version>1.14.0-SNAPSHOT</version>
<name>User Manager Parent</name> <name>User Manager Parent</name>
<packaging>pom</packaging> <packaging>pom</packaging>
......
...@@ -98,8 +98,10 @@ spec: ...@@ -98,8 +98,10 @@ spec:
value: {{ include "app.ssoServerUrl" . }} value: {{ include "app.ssoServerUrl" . }}
- name: KOP_USER_MANAGER_URL - name: KOP_USER_MANAGER_URL
value: {{ include "app.baseUrl" . }} value: {{ include "app.baseUrl" . }}
- name: KOP_KEYCLOAK_SYNC_CRON {{- if ((.Values.ozgcloud).usersync).period }}
value: {{ .Values.kop.keycloak.sync.cron }} - name: OZGCLOUD_USERSYNC_PERIOD
value: {{ .Values.ozgcloud.usersync.period }}
{{- end }}
- name: QUARKUS_HTTP_CORS_ORIGINS - name: QUARKUS_HTTP_CORS_ORIGINS
value: {{ (include "app.goofyAddress" .) }} value: {{ (include "app.goofyAddress" .) }}
{{- with (.Values.env).customList }} {{- with (.Values.env).customList }}
......
...@@ -37,8 +37,8 @@ metadata: ...@@ -37,8 +37,8 @@ metadata:
name: {{ include "app.name" . }} name: {{ include "app.name" . }}
namespace: {{ include "app.namespace" . }} namespace: {{ include "app.namespace" . }}
spec: spec:
{{- if ne (.Values).cluster_env "dataport" }} {{- if and (.Values.ingress).className (ne (.Values).cluster_env "dataport") }}
ingressClassName: nginx ingressClassName: {{ .Values.ingress.className }}
{{- end }} {{- end }}
rules: rules:
- http: - http:
......
...@@ -38,8 +38,6 @@ kop: ...@@ -38,8 +38,6 @@ kop:
keycloak: keycloak:
api: api:
user: userManagerApiUser user: userManagerApiUser
sync:
cron: 0 15 1 * * ?
imageCredentials: imageCredentials:
registry: docker.ozg-sh.de registry: docker.ozg-sh.de
......
...@@ -52,11 +52,6 @@ tests: ...@@ -52,11 +52,6 @@ tests:
content: content:
name: KOP_KEYCLOAK_API_REALM name: KOP_KEYCLOAK_API_REALM
value: sh-helm-test value: sh-helm-test
- contains:
path: spec.template.spec.containers[0].env
content:
name: KOP_KEYCLOAK_SYNC_CRON
value: 0 15 1 * * ?
- contains: - contains:
path: spec.template.spec.containers[0].env path: spec.template.spec.containers[0].env
content: content:
......
...@@ -69,3 +69,19 @@ tests: ...@@ -69,3 +69,19 @@ tests:
content: content:
name: QUARKUS_MONGODB_DATABASE name: QUARKUS_MONGODB_DATABASE
value: test-database value: test-database
- it: check user sync period set
set:
ozgcloud.usersync.period: "6h"
asserts:
- contains:
path: spec.template.spec.containers[0].env
content:
name: OZGCLOUD_USERSYNC_PERIOD
value: "6h"
- it: check user sync period NOT set
asserts:
- notContains:
path: spec.template.spec.containers[0].env
content:
name: OZGCLOUD_USERSYNC_PERIOD
value: "6h"
\ No newline at end of file
...@@ -29,16 +29,23 @@ release: ...@@ -29,16 +29,23 @@ release:
templates: templates:
- templates/ingress.yaml - templates/ingress.yaml
tests: tests:
- it: should create ingress tls/ingressClass - it: should create ingress tls
asserts: asserts:
- equal:
path: spec.ingressClassName
value: nginx
- equal: - equal:
path: spec.tls[0].secretName path: spec.tls[0].secretName
value: helm-user-manager-tls value: helm-user-manager-tls
- it: should not set ingressClassName
- it: should not create ingress tls/ingressClass asserts:
- isNull:
path: spec.ingressClassName
- it: should set ingressClassName
set:
ingress.className: nginx
asserts:
- equal:
path: spec.ingressClassName
value: nginx
- it: should not create ingress tls/ingressClassName
set: set:
cluster_env: dataport cluster_env: dataport
asserts: asserts:
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<groupId>de.itvsh.kop.user</groupId> <groupId>de.itvsh.kop.user</groupId>
<artifactId>user-manager-interface</artifactId> <artifactId>user-manager-interface</artifactId>
<version>1.13.0-SNAPSHOT</version> <version>1.14.0-SNAPSHOT</version>
<name>UserManager Interface</name> <name>UserManager Interface</name>
<description>gRPC Interface for User Manager</description> <description>gRPC Interface for User Manager</description>
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jandex-maven-plugin-version>1.2.3</jandex-maven-plugin-version> <jandex-maven-plugin-version>1.2.3</jandex-maven-plugin-version>
<quarkus.platform.version>3.5.0</quarkus.platform.version>
</properties> </properties>
<dependencies> <dependencies>
......
...@@ -30,13 +30,13 @@ ...@@ -30,13 +30,13 @@
<parent> <parent>
<groupId>de.itvsh.kop.common</groupId> <groupId>de.itvsh.kop.common</groupId>
<artifactId>kop-common-dependencies</artifactId> <artifactId>kop-common-dependencies</artifactId>
<version>1.7.1</version> <version>2.3.1</version>
<relativePath/> <relativePath/>
</parent> </parent>
<groupId>de.itvsh.kop.user</groupId> <groupId>de.itvsh.kop.user</groupId>
<artifactId>user-manager-server</artifactId> <artifactId>user-manager-server</artifactId>
<version>1.13.0-SNAPSHOT</version> <version>1.14.0-SNAPSHOT</version>
<name>User Manager</name> <name>User Manager</name>
<properties> <properties>
...@@ -54,8 +54,12 @@ ...@@ -54,8 +54,12 @@
<lombok.version>1.18.24</lombok.version> <lombok.version>1.18.24</lombok.version>
<jakarta.interceptor.version>1.2.5</jakarta.interceptor.version> <jakarta.interceptor.version>2.1.0</jakarta.interceptor.version>
<jakarta.annotatioin.version>1.3.5</jakarta.annotatioin.version> <jakarta.annotatioin.version>2.1.1</jakarta.annotatioin.version>
<keycloak-adapter.version>22.0.5</keycloak-adapter.version>
<quarkus.platform.version>3.5.0</quarkus.platform.version>
</properties> </properties>
<dependencyManagement> <dependencyManagement>
...@@ -92,6 +96,10 @@ ...@@ -92,6 +96,10 @@
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId> <artifactId>log4j-slf4j-impl</artifactId>
</exclusion> </exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
...@@ -207,11 +215,27 @@ ...@@ -207,11 +215,27 @@
<artifactId>jakarta.interceptor-api</artifactId> <artifactId>jakarta.interceptor-api</artifactId>
<version>${jakarta.interceptor.version}</version> <version>${jakarta.interceptor.version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
</dependency>
<dependency> <dependency>
<groupId>jakarta.annotation</groupId> <groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId> <artifactId>jakarta.annotation-api</artifactId>
<version>${jakarta.annotatioin.version}</version> <version>${jakarta.annotatioin.version}</version>
</dependency> </dependency>
<dependency>
<groupId>jakarta.inject</groupId>
<artifactId>jakarta.inject-api</artifactId>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
...@@ -290,7 +314,7 @@ ...@@ -290,7 +314,7 @@
<compilerArgs> <compilerArgs>
<arg>-parameters</arg> <arg>-parameters</arg>
<compilerArg> <compilerArg>
-Amapstruct.defaultComponentModel=cdi -Amapstruct.defaultComponentModel=jakarta
</compilerArg> </compilerArg>
<compilerArg> <compilerArg>
-Amapstruct.unmappedTargetPolicy=WARN -Amapstruct.unmappedTargetPolicy=WARN
......
package de.itvsh.kop.user;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import lombok.Builder;
import lombok.Getter;
import lombok.Singular;
@Builder
@Getter
class RoleHierarchy {
private final String roleName;
@Singular
private List<RoleHierarchy> subRoles;
public List<String> getFlattenedHierarchy(String roleName) {
var subRoles = new ArrayDeque<String>();
collectSubRoles(this, roleName, subRoles);
return subRoles.stream().toList();
}
boolean collectSubRoles(RoleHierarchy role, String roleName, Deque<String> subRoles) {
subRoles.addLast(role.getRoleName());
if (Objects.equals(role.getRoleName(), roleName)) {
return true;
}
for (var subRole : role.getSubRoles()) {
if (collectSubRoles(subRole, roleName, subRoles)) {
return true;
}
}
subRoles.removeLast();
return false;
}
}
...@@ -26,13 +26,13 @@ package de.itvsh.kop.user; ...@@ -26,13 +26,13 @@ package de.itvsh.kop.user;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.inject.Inject; import jakarta.inject.Inject;
import javax.ws.rs.GET; import jakarta.ws.rs.GET;
import javax.ws.rs.Path; import jakarta.ws.rs.Path;
import javax.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
import javax.ws.rs.Produces; import jakarta.ws.rs.Produces;
import javax.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.resteasy.reactive.common.util.RestMediaType; import org.jboss.resteasy.reactive.common.util.RestMediaType;
...@@ -80,7 +80,7 @@ public class UserProfileResource { ...@@ -80,7 +80,7 @@ public class UserProfileResource {
Stream<User> users; Stream<User> users;
if (deleted.isEmpty()) { if (deleted.isEmpty()) {
users = userService.findUsers(query); users = userService.findUsers(query);
} else if (deleted.get()) { } else if (deleted.orElse(false)) {
users = userService.findInactiveUsers(query); users = userService.findInactiveUsers(query);
} else { } else {
users = userService.findActiveUsers(query); users = userService.findActiveUsers(query);
......
...@@ -25,8 +25,8 @@ package de.itvsh.kop.user; ...@@ -25,8 +25,8 @@ package de.itvsh.kop.user;
import java.util.List; import java.util.List;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.ws.rs.core.Link; import jakarta.ws.rs.core.Link;
import de.itvsh.kop.user.settings.UserSettingsResource; import de.itvsh.kop.user.settings.UserSettingsResource;
import io.quarkus.hal.HalCollectionWrapper; import io.quarkus.hal.HalCollectionWrapper;
......
...@@ -28,7 +28,7 @@ import static de.itvsh.kop.user.User.*; ...@@ -28,7 +28,7 @@ import static de.itvsh.kop.user.User.*;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import org.bson.types.ObjectId; import org.bson.types.ObjectId;
......
...@@ -32,7 +32,7 @@ import java.util.Objects; ...@@ -32,7 +32,7 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UserResource;
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
*/ */
package de.itvsh.kop.user; package de.itvsh.kop.user;
import java.util.Collection;
import java.util.Collections;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
...@@ -32,4 +35,17 @@ public class UserRole { ...@@ -32,4 +35,17 @@ public class UserRole {
public static final String EINHEITLICHER_ANSPRECHPARTNER = "EINHEITLICHER_ANSPRECHPARTNER"; public static final String EINHEITLICHER_ANSPRECHPARTNER = "EINHEITLICHER_ANSPRECHPARTNER";
public static final String VERWALTUNG_POSTSTELLE = "VERWALTUNG_POSTSTELLE"; public static final String VERWALTUNG_POSTSTELLE = "VERWALTUNG_POSTSTELLE";
public static final String VERWALTUNG_USER = "VERWALTUNG_USER"; public static final String VERWALTUNG_USER = "VERWALTUNG_USER";
public static final String VERWALTUNG_LOESCHEN = "VERWALTUNG_LOESCHEN";
private static final RoleHierarchy HIERARCHY = RoleHierarchy.builder()
.roleName(VERWALTUNG_LOESCHEN)
.subRole(RoleHierarchy.builder()
.roleName(VERWALTUNG_USER)
.build())
.build();
public static boolean containsWithinRoleHierarchy(Collection<String> userRoles, String roleName) {
return !Collections.disjoint(userRoles, HIERARCHY.getFlattenedHierarchy(roleName));
}
} }
\ No newline at end of file
...@@ -26,8 +26,8 @@ package de.itvsh.kop.user; ...@@ -26,8 +26,8 @@ package de.itvsh.kop.user;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
......
...@@ -28,10 +28,10 @@ import java.util.List; ...@@ -28,10 +28,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import javax.inject.Inject; import jakarta.inject.Inject;
import javax.json.JsonArray; import jakarta.json.JsonArray;
import javax.json.JsonString; import jakarta.json.JsonString;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.eclipse.microprofile.jwt.JsonWebToken; import org.eclipse.microprofile.jwt.JsonWebToken;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment