KEYCLOAK-1944
Remove winzipaes import/export provider
This commit is contained in:
parent
2deb20a2c9
commit
4fbf6841be
22 changed files with 3 additions and 551 deletions
16
dependencies/server-all/pom.xml
vendored
16
dependencies/server-all/pom.xml
vendored
|
@ -141,22 +141,6 @@
|
||||||
<artifactId>mongo-java-driver</artifactId>
|
<artifactId>mongo-java-driver</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- export/import -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-export-import-zip</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.idyl</groupId>
|
|
||||||
<artifactId>winzipaes</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.bouncycastle</groupId>
|
|
||||||
<artifactId>bcprov-jdk16</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.liquibase</groupId>
|
<groupId>org.liquibase</groupId>
|
||||||
<artifactId>liquibase-core</artifactId>
|
<artifactId>liquibase-core</artifactId>
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.3" name="de.idyl.winzipaes">
|
|
||||||
<resources>
|
|
||||||
<artifact name="${de.idyl:winzipaes}"/>
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
<module name="org.bouncycastle"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.3" name="org.keycloak.keycloak-export-import-zip">
|
|
||||||
<resources>
|
|
||||||
<artifact name="${org.keycloak:keycloak-export-import-zip}"/>
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="org.keycloak.keycloak-common"/>
|
|
||||||
<module name="org.keycloak.keycloak-core"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-api"/>
|
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-model"/>
|
|
||||||
<module name="org.keycloak.keycloak-export-import-api"/>
|
|
||||||
<module name="javax.ws.rs.api"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
|
||||||
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
|
|
||||||
<module name="org.jboss.logging"/>
|
|
||||||
<module name="org.bouncycastle" />
|
|
||||||
<module name="de.idyl.winzipaes"/>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -21,7 +21,6 @@
|
||||||
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-zip" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-zip" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
||||||
|
|
|
@ -278,15 +278,6 @@
|
||||||
<maven-resource group="org.mongodb" artifact="mongo-java-driver"/>
|
<maven-resource group="org.mongodb" artifact="mongo-java-driver"/>
|
||||||
</module-def>
|
</module-def>
|
||||||
|
|
||||||
<!-- export/import -->
|
|
||||||
|
|
||||||
<module-def name="org.keycloak.keycloak-export-import-zip">
|
|
||||||
<maven-resource group="org.keycloak" artifact="keycloak-export-import-zip"/>
|
|
||||||
</module-def>
|
|
||||||
<module-def name="de.idyl.winzipaes">
|
|
||||||
<maven-resource group="de.idyl" artifact="winzipaes"/>
|
|
||||||
</module-def>
|
|
||||||
|
|
||||||
<module-def name="org.liquibase">
|
<module-def name="org.liquibase">
|
||||||
<maven-resource group="org.liquibase" artifact="liquibase-core"/>
|
<maven-resource group="org.liquibase" artifact="liquibase-core"/>
|
||||||
</module-def>
|
</module-def>
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.1" name="de.idyl.winzipaes">
|
|
||||||
<resources>
|
|
||||||
<!-- Insert resources here -->
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -21,7 +21,6 @@
|
||||||
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-zip" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-export-import-zip">
|
|
||||||
<resources>
|
|
||||||
<!-- Insert resources here -->
|
|
||||||
</resources>
|
|
||||||
<dependencies>
|
|
||||||
<module name="org.keycloak.keycloak-common"/>
|
|
||||||
<module name="org.keycloak.keycloak-core"/>
|
|
||||||
<module name="org.keycloak.keycloak-model-api"/>
|
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-model"/>
|
|
||||||
<module name="org.keycloak.keycloak-export-import-api"/>
|
|
||||||
<module name="javax.ws.rs.api"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-core-asl"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-mapper-asl"/>
|
|
||||||
<module name="org.codehaus.jackson.jackson-xc"/>
|
|
||||||
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
|
|
||||||
<module name="org.jboss.logging"/>
|
|
||||||
<module name="org.bouncycastle" />
|
|
||||||
<module name="de.idyl.winzipaes"/>
|
|
||||||
<module name="javax.api"/>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</module>
|
|
|
@ -31,7 +31,6 @@
|
||||||
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-api" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-dir" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
<module name="org.keycloak.keycloak-export-import-single-file" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-export-import-zip" services="import"/>
|
|
||||||
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-freemarker" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
<module name="org.keycloak.keycloak-forms-common-themes" services="import"/>
|
||||||
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
<module name="org.keycloak.keycloak-invalidation-cache-infinispan" services="import"/>
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
<outputDirectory>modules/system/layers/base</outputDirectory>
|
<outputDirectory>modules/system/layers/base</outputDirectory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>com/google/zxing/**</include>
|
<include>com/google/zxing/**</include>
|
||||||
<include>de/idyl/winzipaes/**</include>
|
|
||||||
<include>org/freemarker/**</include>
|
<include>org/freemarker/**</include>
|
||||||
<include>org/keycloak/**</include>
|
<include>org/keycloak/**</include>
|
||||||
<include>org/liquibase/**</include>
|
<include>org/liquibase/**</include>
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
<para>
|
<para>
|
||||||
You can export/import your database either to:
|
You can export/import your database either to:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>Encrypted ZIP file on local filesystem</listitem>
|
|
||||||
<listitem>Directory on local filesystem</listitem>
|
<listitem>Directory on local filesystem</listitem>
|
||||||
<listitem>Single JSON file on your filesystem</listitem>
|
<listitem>Single JSON file on your filesystem</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
When importing using the "dir" or "zip" strategies, note that the files need to follow the naming convention specified below.
|
When importing using the "dir" strategy, note that the files need to follow the naming convention specified below.
|
||||||
If you are importing files which were previously exported, the files already follow this convention.
|
If you are importing files which were previously exported, the files already follow this convention.
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>{REALM_NAME}-realm.json, such as "acme-roadrunner-affairs-realm.json" for the realm named "acme-roadrunner-affairs"</listitem>
|
<listitem>{REALM_NAME}-realm.json, such as "acme-roadrunner-affairs-realm.json" for the realm named "acme-roadrunner-affairs"</listitem>
|
||||||
|
@ -21,26 +20,10 @@
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
Encrypted ZIP is recommended as export contains many sensitive informations like passwords of your users (even if they are hashed),
|
If you import to Directory, you can specify also the number of users to be stored in each JSON file. So if you have
|
||||||
but also their email addresses, and especially private keys of the realms. Directory and Single JSON file are useful especially
|
|
||||||
for testing as data in the files are not protected. On the other hand, it's useful if you want to look at all your data in JSON
|
|
||||||
files directly.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you import to ZIP or Directory, you can specify also the number of users to be stored in each JSON file. So if you have
|
|
||||||
very large amount of users in your database, you likely don't want to import them into single file as the file might be very big.
|
very large amount of users in your database, you likely don't want to import them into single file as the file might be very big.
|
||||||
Processing of each file is done in separate transaction as exporting/importing all users at once could also lead to memory issues.
|
Processing of each file is done in separate transaction as exporting/importing all users at once could also lead to memory issues.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
So to export the content of your Keycloak database into encrypted ZIP, you can execute Keycloak server with the System properties like:
|
|
||||||
<programlisting><![CDATA[
|
|
||||||
bin/standalone.sh -Dkeycloak.migration.action=export
|
|
||||||
-Dkeycloak.migration.provider=zip -Dkeycloak.migration.zipFile=<FILE TO EXPORT TO>
|
|
||||||
-Dkeycloak.migration.zipPassword=<PASSWORD TO DECRYPT EXPORT>
|
|
||||||
]]></programlisting>
|
|
||||||
Then you can move or copy the encrypted ZIP file into second environment and you can trigger import from it into Keycloak server with the same command but use
|
|
||||||
<literal>-Dkeycloak.migration.action=import</literal> instead of <literal>export</literal> .
|
|
||||||
</para>
|
|
||||||
<para>
|
<para>
|
||||||
To export into unencrypted directory you can use:
|
To export into unencrypted directory you can use:
|
||||||
<programlisting><![CDATA[
|
<programlisting><![CDATA[
|
||||||
|
@ -80,7 +63,7 @@ bin/standalone.sh -Dkeycloak.migration.action=import
|
||||||
<term>-Dkeycloak.migration.usersExportStrategy</term>
|
<term>-Dkeycloak.migration.usersExportStrategy</term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
can be used to specify for ZIP or Directory providers to specify where to import users.
|
can be used to specify for Directory providers to specify where to import users.
|
||||||
Possible values are:
|
Possible values are:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>DIFFERENT_FILES - Users will be exported into more different files according to maximum number of users per file. This is default value</listitem>
|
<listitem>DIFFERENT_FILES - Users will be exported into more different files according to maximum number of users per file. This is default value</listitem>
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<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>keycloak-export-import-parent</artifactId>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<version>1.6.0.Final-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>keycloak-export-import-zip</artifactId>
|
|
||||||
<name>Keycloak Export Import To Encrypted ZIP</name>
|
|
||||||
<description/>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-core</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-model-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-export-import-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.codehaus.jackson</groupId>
|
|
||||||
<artifactId>jackson-core-asl</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.codehaus.jackson</groupId>
|
|
||||||
<artifactId>jackson-mapper-asl</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jboss.logging</groupId>
|
|
||||||
<artifactId>jboss-logging</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.idyl</groupId>
|
|
||||||
<artifactId>winzipaes</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>${maven.compiler.source}</source>
|
|
||||||
<target>${maven.compiler.target}</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,82 +0,0 @@
|
||||||
package org.keycloak.exportimport.zip;
|
|
||||||
|
|
||||||
import de.idyl.winzipaes.AesZipFileEncrypter;
|
|
||||||
import de.idyl.winzipaes.impl.AESEncrypter;
|
|
||||||
import de.idyl.winzipaes.impl.AESEncrypterBC;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.keycloak.representations.VersionRepresentation;
|
|
||||||
import org.keycloak.exportimport.util.ExportUtils;
|
|
||||||
import org.keycloak.exportimport.util.MultipleStepsExportProvider;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.RealmModel;
|
|
||||||
import org.keycloak.models.UserModel;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.util.JsonSerialization;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class ZipExportProvider extends MultipleStepsExportProvider {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ZipExportProvider.class);
|
|
||||||
|
|
||||||
private final AesZipFileEncrypter encrypter;
|
|
||||||
private final String password;
|
|
||||||
|
|
||||||
public ZipExportProvider(File zipFile, String password) {
|
|
||||||
if (zipFile.exists()) {
|
|
||||||
throw new IllegalStateException("File " + zipFile.getAbsolutePath() + " already exists");
|
|
||||||
}
|
|
||||||
this.password = password;
|
|
||||||
|
|
||||||
try {
|
|
||||||
AESEncrypter encrypter = new AESEncrypterBC();
|
|
||||||
this.encrypter = new AesZipFileEncrypter(zipFile, encrypter);
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new RuntimeException(ioe);
|
|
||||||
}
|
|
||||||
logger.infof("Exporting into zip file %s", zipFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeRealm(String fileName, RealmRepresentation rep) throws IOException {
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
JsonSerialization.mapper.writeValue(stream, rep);
|
|
||||||
writeStream(fileName, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeUsers(String fileName, KeycloakSession session, RealmModel realm, List<UserModel> users) throws IOException {
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
ExportUtils.exportUsersToStream(session, realm, users, JsonSerialization.mapper, stream);
|
|
||||||
writeStream(fileName, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void writeVersion(String fileName, VersionRepresentation version) throws IOException {
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
|
||||||
JsonSerialization.mapper.writeValue(stream, version);
|
|
||||||
writeStream(fileName, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeStream(String fileName, ByteArrayOutputStream stream) throws IOException {
|
|
||||||
byte[] byteArray = stream.toByteArray();
|
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
|
|
||||||
this.encrypter.add(fileName, bis, this.password);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
this.encrypter.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new RuntimeException(ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package org.keycloak.exportimport.zip;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.exportimport.ExportImportConfig;
|
|
||||||
import org.keycloak.exportimport.ExportProvider;
|
|
||||||
import org.keycloak.exportimport.ExportProviderFactory;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class ZipExportProviderFactory implements ExportProviderFactory {
|
|
||||||
|
|
||||||
|
|
||||||
public static final String PROVIDER_ID = "zip";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExportProvider create(KeycloakSession session) {
|
|
||||||
String fileName = ExportImportConfig.getZipFile();
|
|
||||||
String password = ExportImportConfig.getZipPassword();
|
|
||||||
if (fileName == null) {
|
|
||||||
throw new IllegalArgumentException("ZIP file for export not provided");
|
|
||||||
}
|
|
||||||
if (password == null) {
|
|
||||||
throw new IllegalArgumentException("Password for encrypting ZIP not provided");
|
|
||||||
}
|
|
||||||
return new ZipExportProvider(new File(fileName), password);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return PROVIDER_ID;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +0,0 @@
|
||||||
package org.keycloak.exportimport.zip;
|
|
||||||
|
|
||||||
import de.idyl.winzipaes.AesZipFileDecrypter;
|
|
||||||
import de.idyl.winzipaes.impl.AESDecrypter;
|
|
||||||
import de.idyl.winzipaes.impl.AESDecrypterBC;
|
|
||||||
import de.idyl.winzipaes.impl.ExtZipEntry;
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.exportimport.ImportProvider;
|
|
||||||
import org.keycloak.exportimport.Strategy;
|
|
||||||
import org.keycloak.exportimport.util.ExportImportSessionTask;
|
|
||||||
import org.keycloak.exportimport.util.ImportUtils;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
|
||||||
import org.keycloak.util.JsonSerialization;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.zip.DataFormatException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class ZipImportProvider implements ImportProvider {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ZipImportProvider.class);
|
|
||||||
|
|
||||||
private final AesZipFileDecrypter decrypter;
|
|
||||||
private final String password;
|
|
||||||
|
|
||||||
public ZipImportProvider(File zipFile, String password) {
|
|
||||||
try {
|
|
||||||
if (!zipFile.exists()) {
|
|
||||||
throw new IllegalStateException("File " + zipFile.getAbsolutePath() + " doesn't exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
AESDecrypter decrypter = new AESDecrypterBC();
|
|
||||||
this.decrypter = new AesZipFileDecrypter(zipFile, decrypter);
|
|
||||||
this.password = password;
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new RuntimeException(ioe);
|
|
||||||
}
|
|
||||||
logger.infof("Importing from ZIP file %s", zipFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void importModel(KeycloakSessionFactory factory, Strategy strategy) throws IOException {
|
|
||||||
List<String> realmNames = getRealmsToImport();
|
|
||||||
|
|
||||||
for (String realmName : realmNames) {
|
|
||||||
importRealm(factory, realmName, strategy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isMasterRealmExported() throws IOException {
|
|
||||||
List<String> realmNames = getRealmsToImport();
|
|
||||||
return realmNames.contains(Config.getAdminRealm());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<String> getRealmsToImport() throws IOException {
|
|
||||||
List<String> realmNames = new ArrayList<String>();
|
|
||||||
for (ExtZipEntry entry : this.decrypter.getEntryList()) {
|
|
||||||
String entryName = entry.getName();
|
|
||||||
if (entryName.endsWith("-realm.json")) {
|
|
||||||
// Parse "foo" from "foo-realm.json"
|
|
||||||
String realmName = entryName.substring(0, entryName.length() - 11);
|
|
||||||
|
|
||||||
// Ensure that master realm is imported first
|
|
||||||
if (Config.getAdminRealm().equals(realmName)) {
|
|
||||||
realmNames.add(0, realmName);
|
|
||||||
} else {
|
|
||||||
realmNames.add(realmName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return realmNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void importRealm(KeycloakSessionFactory factory, final String realmName, final Strategy strategy) throws IOException {
|
|
||||||
try {
|
|
||||||
// Import realm first
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
||||||
this.decrypter.extractEntry(this.decrypter.getEntry(realmName + "-realm.json"), bos, this.password);
|
|
||||||
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
|
|
||||||
final RealmRepresentation realmRep = JsonSerialization.mapper.readValue(bis, RealmRepresentation.class);
|
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void runExportImportTask(KeycloakSession session) throws IOException {
|
|
||||||
ImportUtils.importRealm(session, realmRep, strategy);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Import users
|
|
||||||
for (ExtZipEntry entry : this.decrypter.getEntryList()) {
|
|
||||||
String name = entry.getName();
|
|
||||||
if (name.matches(realmName + "-users-[0-9]+\\.json")) {
|
|
||||||
bos = new ByteArrayOutputStream();
|
|
||||||
this.decrypter.extractEntry(entry, bos, this.password);
|
|
||||||
final ByteArrayInputStream bis2 = new ByteArrayInputStream(bos.toByteArray());
|
|
||||||
|
|
||||||
KeycloakModelUtils.runJobInTransaction(factory, new ExportImportSessionTask() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void runExportImportTask(KeycloakSession session) throws IOException {
|
|
||||||
ImportUtils.importUsersFromStream(session, realmName, JsonSerialization.mapper, bis2);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
throw new RuntimeException(dfe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
try {
|
|
||||||
this.decrypter.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new RuntimeException(ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package org.keycloak.exportimport.zip;
|
|
||||||
|
|
||||||
import org.keycloak.Config;
|
|
||||||
import org.keycloak.exportimport.ExportImportConfig;
|
|
||||||
import org.keycloak.exportimport.ImportProvider;
|
|
||||||
import org.keycloak.exportimport.ImportProviderFactory;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
|
||||||
*/
|
|
||||||
public class ZipImportProviderFactory implements ImportProviderFactory {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImportProvider create(KeycloakSession session) {
|
|
||||||
String fileName = ExportImportConfig.getZipFile();
|
|
||||||
String password = ExportImportConfig.getZipPassword();
|
|
||||||
if (fileName == null) {
|
|
||||||
throw new IllegalArgumentException("ZIP file for import not provided");
|
|
||||||
}
|
|
||||||
if (password == null) {
|
|
||||||
throw new IllegalArgumentException("Password for decrypting ZIP not provided");
|
|
||||||
}
|
|
||||||
return new ZipImportProvider(new File(fileName), password);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Config.Scope config) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postInit(KeycloakSessionFactory factory) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return ZipExportProviderFactory.PROVIDER_ID;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
org.keycloak.exportimport.zip.ZipExportProviderFactory
|
|
|
@ -1 +0,0 @@
|
||||||
org.keycloak.exportimport.zip.ZipImportProviderFactory
|
|
|
@ -18,7 +18,6 @@
|
||||||
<module>export-import-api</module>
|
<module>export-import-api</module>
|
||||||
<module>export-import-dir</module>
|
<module>export-import-dir</module>
|
||||||
<module>export-import-single-file</module>
|
<module>export-import-single-file</module>
|
||||||
<module>export-import-zip</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
13
pom.xml
13
pom.xml
|
@ -58,7 +58,6 @@
|
||||||
<servlet.api.30.version>1.0.2.Final</servlet.api.30.version>
|
<servlet.api.30.version>1.0.2.Final</servlet.api.30.version>
|
||||||
<google.zxing.version>3.2.1</google.zxing.version>
|
<google.zxing.version>3.2.1</google.zxing.version>
|
||||||
<github.relaxng.version>2011.1</github.relaxng.version>
|
<github.relaxng.version>2011.1</github.relaxng.version>
|
||||||
<winzipaes.version>1.0.1</winzipaes.version>
|
|
||||||
<freemarker.version>2.3.23</freemarker.version>
|
<freemarker.version>2.3.23</freemarker.version>
|
||||||
<twitter4j.version>4.0.4</twitter4j.version>
|
<twitter4j.version>4.0.4</twitter4j.version>
|
||||||
<selenium.version>2.35.0</selenium.version>
|
<selenium.version>2.35.0</selenium.version>
|
||||||
|
@ -373,13 +372,6 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Encrypted ZIP -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>de.idyl</groupId>
|
|
||||||
<artifactId>winzipaes</artifactId>
|
|
||||||
<version>${winzipaes.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Apache DS -->
|
<!-- Apache DS -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.directory.server</groupId>
|
<groupId>org.apache.directory.server</groupId>
|
||||||
|
@ -700,11 +692,6 @@
|
||||||
<artifactId>keycloak-export-import-single-file</artifactId>
|
<artifactId>keycloak-export-import-single-file</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.keycloak</groupId>
|
|
||||||
<artifactId>keycloak-export-import-zip</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.keycloak</groupId>
|
<groupId>org.keycloak</groupId>
|
||||||
<artifactId>keycloak-kerberos-federation</artifactId>
|
<artifactId>keycloak-kerberos-federation</artifactId>
|
||||||
|
|
|
@ -10,7 +10,6 @@ import org.keycloak.exportimport.ExportImportConfig;
|
||||||
import org.keycloak.exportimport.dir.DirExportProvider;
|
import org.keycloak.exportimport.dir.DirExportProvider;
|
||||||
import org.keycloak.exportimport.dir.DirExportProviderFactory;
|
import org.keycloak.exportimport.dir.DirExportProviderFactory;
|
||||||
import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
|
import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory;
|
||||||
import org.keycloak.exportimport.zip.ZipExportProviderFactory;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmProvider;
|
import org.keycloak.models.RealmProvider;
|
||||||
|
@ -217,30 +216,6 @@ public class ExportImportTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testZipFullExportImport() throws Throwable {
|
|
||||||
ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID);
|
|
||||||
String zipFilePath = getExportImportTestDirectory() + File.separator + "export-full.zip";
|
|
||||||
new File(zipFilePath).delete();
|
|
||||||
ExportImportConfig.setZipFile(zipFilePath);
|
|
||||||
ExportImportConfig.setZipPassword("encPassword");
|
|
||||||
ExportImportConfig.setUsersPerFile(ExportImportConfig.DEFAULT_USERS_PER_FILE);
|
|
||||||
|
|
||||||
testFullExportImport();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testZipRealmExportImport() throws Throwable {
|
|
||||||
ExportImportConfig.setProvider(ZipExportProviderFactory.PROVIDER_ID);
|
|
||||||
String zipFilePath = getExportImportTestDirectory() + File.separator + "export-realm.zip";
|
|
||||||
new File(zipFilePath).delete();
|
|
||||||
ExportImportConfig.setZipFile(zipFilePath);
|
|
||||||
ExportImportConfig.setZipPassword("encPassword");
|
|
||||||
ExportImportConfig.setUsersPerFile(3);
|
|
||||||
|
|
||||||
testRealmExportImport();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testFullExportImport() {
|
private void testFullExportImport() {
|
||||||
ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
|
ExportImportConfig.setAction(ExportImportConfig.ACTION_EXPORT);
|
||||||
ExportImportConfig.setRealmName(null);
|
ExportImportConfig.setRealmName(null);
|
||||||
|
|
Loading…
Reference in a new issue