Skip to content

Commit

Permalink
Migrate Elytron Security JDBC config classes to @ConfigMappin
Browse files Browse the repository at this point in the history
  • Loading branch information
michalvavrik committed Mar 18, 2024
1 parent 6236798 commit 9678bc5
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ void configureJdbcRealmAuthConfig(JdbcRecorder recorder,
BuildProducer<SecurityRealmBuildItem> securityRealm,
BeanContainerBuildItem beanContainerBuildItem, //we need this to make sure ArC is initialized
List<JdbcDataSourceBuildItem> dataSourcesConfigured) throws Exception {
if (!jdbcSecurityRealmBuildTimeConfig.enabled) {
if (!jdbcSecurityRealmBuildTimeConfig.enabled()) {
return;
}

RuntimeValue<SecurityRealm> realm = recorder.createRealm(jdbcSecurityRealmRuntimeConfig);
securityRealm.produce(new SecurityRealmBuildItem(realm, jdbcSecurityRealmBuildTimeConfig.realmName, null));
securityRealm.produce(new SecurityRealmBuildItem(realm, jdbcSecurityRealmBuildTimeConfig.realmName(), null));
}

@BuildStep
ElytronPasswordMarkerBuildItem marker(JdbcSecurityRealmBuildTimeConfig jdbcSecurityRealmBuildTimeConfig) {
if (!jdbcSecurityRealmBuildTimeConfig.enabled) {
if (!jdbcSecurityRealmBuildTimeConfig.enabled()) {
return null;
}
return new ElytronPasswordMarkerBuildItem();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
package io.quarkus.elytron.security.jdbc;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;

/**
* Configuration information used to populate a {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.AttributeMapper}
*/
@ConfigGroup
public class AttributeMappingConfig {
public interface AttributeMappingConfig {

/**
* The index (1 based numbering) of column to map
*/
@ConfigItem
public int index;
@WithDefault("0")
int index();

/**
* The target attribute name
*/
@ConfigItem
public String to;
String to();

@Override
public String toString() {
return "AttributeMappingConfig{" +
"index=" + index +
", to='" + to + '\'' +
'}';
}
String toString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,63 @@
import org.wildfly.security.password.spec.Encoding;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;

/**
* Configuration information used to populate a "bcrypt"
* {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper}
*/
@ConfigGroup
public class BcryptPasswordKeyMapperConfig implements PasswordKeyMapperConfig {
public interface BcryptPasswordKeyMapperConfig {

public static final String BCRYPT = "bcrypt";
String BCRYPT = "bcrypt";

/**
* If the bcrypt-password-mapper is enabled.
*/
@ConfigItem
public boolean enabled;
@WithDefault("false")
boolean enabled();

/**
* The index (1 based numbering) of the column containing the password hash
*/
@ConfigItem
public int passwordIndex;
@WithDefault("0")
int passwordIndex();

/**
* A string referencing the password hash encoding ("BASE64" or "HEX")
*/
@ConfigItem(defaultValue = "BASE64")
public Encoding hashEncoding;
@WithDefault("BASE64")
Encoding hashEncoding();

/**
* The index (1 based numbering) of the column containing the Bcrypt salt
*/
@ConfigItem
public int saltIndex;
@WithDefault("0")
int saltIndex();

/**
* A string referencing the salt encoding ("BASE64" or "HEX")
*/
@ConfigItem(defaultValue = "BASE64")
public Encoding saltEncoding;
@WithDefault("BASE64")
Encoding saltEncoding();

/**
* The index (1 based numbering) of the column containing the Bcrypt iteration count
*/
@ConfigItem
public int iterationCountIndex;
@WithDefault("0")
int iterationCountIndex();

@Override
public PasswordKeyMapper toPasswordKeyMapper() {
default PasswordKeyMapper toPasswordKeyMapper() {
return PasswordKeyMapper.builder()
.setDefaultAlgorithm(BCRYPT)
.setHashColumn(passwordIndex)
.setHashEncoding(hashEncoding)
.setSaltColumn(saltIndex)
.setSaltEncoding(saltEncoding)
.setIterationCountColumn(iterationCountIndex)
.setHashColumn(passwordIndex())
.setHashEncoding(hashEncoding())
.setSaltColumn(saltIndex())
.setSaltEncoding(saltEncoding())
.setIterationCountColumn(iterationCountIndex())
.build();
}

@Override
public String toString() {
return "BcryptPasswordKeyMapperConfig{" +
"enabled=" + enabled +
", passwordIndex=" + passwordIndex +
", hashEncoding=" + hashEncoding +
", saltIndex=" + saltIndex +
", saltEncoding=" + saltEncoding +
", iterationCountIndex=" + iterationCountIndex +
'}';
}
String toString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,35 @@
import org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithDefault;

/**
* Configuration information used to populate a "clear"
* {@linkplain org.wildfly.security.auth.realm.jdbc.mapper.PasswordKeyMapper}
*/
@ConfigGroup
public class ClearPasswordMapperConfig implements PasswordKeyMapperConfig {
public interface ClearPasswordMapperConfig {

public static final String CLEAR = "clear";
String CLEAR = "clear";

/**
* If the clear-password-mapper is enabled.
*/
@ConfigItem
public boolean enabled;
@WithDefault("false")
boolean enabled();

/**
* The index (1 based numbering) of the column containing the clear password
*/
@ConfigItem(defaultValue = "1")
public int passwordIndex;
@WithDefault("1")
int passwordIndex();

@Override
public PasswordKeyMapper toPasswordKeyMapper() {
default PasswordKeyMapper toPasswordKeyMapper() {
return PasswordKeyMapper.builder()
.setDefaultAlgorithm(CLEAR)
.setHashColumn(passwordIndex)
.setHashColumn(passwordIndex())
.build();
}

@Override
public String toString() {
return "ClearPasswordMapperConfig{" +
"enabled=" + enabled +
", passwordIndex=" + passwordIndex +
'}';
}
String toString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,38 @@ public Provider[] get() {
}
};
JdbcSecurityRealmBuilder builder = JdbcSecurityRealm.builder().setProviders(providers);
PrincipalQueriesConfig principalQueries = config.principalQueries;
registerPrincipalQuery(principalQueries.defaultPrincipalQuery, builder);
principalQueries.namedPrincipalQueries
PrincipalQueriesConfig principalQueries = config.principalQueries();
registerPrincipalQuery(principalQueries.defaultPrincipalQuery(), builder);
principalQueries.namedPrincipalQueries()
.forEach((name, principalQuery) -> registerPrincipalQuery(principalQuery, builder));
return new RuntimeValue<>(builder.build());
}

private void registerPrincipalQuery(PrincipalQueryConfig principalQuery, JdbcSecurityRealmBuilder builder) {

QueryBuilder queryBuilder = builder.principalQuery(principalQuery.sql.orElseThrow(
QueryBuilder queryBuilder = builder.principalQuery(principalQuery.sql().orElseThrow(
() -> new IllegalStateException("quarkus.security.jdbc.principal-query.sql property must be set")))
.from(getDataSource(principalQuery));

AttributeMapper[] mappers = principalQuery.attributeMappings.entrySet()
AttributeMapper[] mappers = principalQuery.attributeMappings().entrySet()
.stream()
.map(entry -> new AttributeMapper(entry.getValue().index, entry.getValue().to))
.map(entry -> new AttributeMapper(entry.getValue().index(), entry.getValue().to()))
.toArray(size -> new AttributeMapper[size]);
queryBuilder.withMapper(mappers);

if (principalQuery.clearPasswordMapperConfig.enabled) {
queryBuilder.withMapper(principalQuery.clearPasswordMapperConfig.toPasswordKeyMapper());
if (principalQuery.clearPasswordMapperConfig().enabled()) {
queryBuilder.withMapper(principalQuery.clearPasswordMapperConfig().toPasswordKeyMapper());
}
if (principalQuery.bcryptPasswordKeyMapperConfig.enabled) {
queryBuilder.withMapper(principalQuery.bcryptPasswordKeyMapperConfig.toPasswordKeyMapper());
if (principalQuery.bcryptPasswordKeyMapperConfig().enabled()) {
queryBuilder.withMapper(principalQuery.bcryptPasswordKeyMapperConfig().toPasswordKeyMapper());
}
}

private DataSource getDataSource(PrincipalQueryConfig principalQuery) {
if (principalQuery.datasource.isPresent()) {
if (principalQuery.datasource().isPresent()) {
return Arc.container()
.instance(DataSource.class,
new io.quarkus.agroal.DataSource.DataSourceLiteral(principalQuery.datasource.get()))
new io.quarkus.agroal.DataSource.DataSourceLiteral(principalQuery.datasource().get()))
.get();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
package io.quarkus.elytron.security.jdbc;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithDefault;

/**
* A configuration object for a jdbc based realm configuration,
* {@linkplain org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm}
*/
@ConfigRoot(name = "security.jdbc", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public class JdbcSecurityRealmBuildTimeConfig {
@ConfigMapping(prefix = "quarkus.security.jdbc")
@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public interface JdbcSecurityRealmBuildTimeConfig {

/**
* The realm name
*/
@ConfigItem(defaultValue = "Quarkus")
public String realmName;
@WithDefault("Quarkus")
String realmName();

/**
* If the properties store is enabled.
*/
@ConfigItem
public boolean enabled;
@WithDefault("false")
boolean enabled();

@Override
public String toString() {
return "JdbcRealmConfig{" +
", realmName='" + realmName + '\'' +
", enabled=" + enabled +
'}';
}
String toString();
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
package io.quarkus.elytron.security.jdbc;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
import io.smallrye.config.WithName;

/**
* A configuration object for a jdbc based realm configuration,
* {@linkplain org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm}
*/
@ConfigRoot(name = "security.jdbc", phase = ConfigPhase.RUN_TIME)
public class JdbcSecurityRealmRuntimeConfig {
@ConfigMapping(prefix = "quarkus.security.jdbc")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
public interface JdbcSecurityRealmRuntimeConfig {

/**
* The principal-queries config
*/
@ConfigItem(name = "principal-query")
public PrincipalQueriesConfig principalQueries;
@WithName("principal-query")
PrincipalQueriesConfig principalQueries();
// https://github.com/wildfly/wildfly-core/blob/main/elytron/src/test/resources/org/wildfly/extension/elytron/security-realms.xml#L18

@Override
public String toString() {
return "JdbcRealmConfig{" +
"principalQueries=" + principalQueries +
'}';
}
String toString();
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,25 @@
import java.util.Map;

import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.ConfigItem;
import io.smallrye.config.WithParentName;

/**
* Container for a default and optionals named {@linkplain io.quarkus.elytron.security.runtime.jdbc.PrincipalQueryConfig}
*/
@ConfigGroup
public class PrincipalQueriesConfig {
public interface PrincipalQueriesConfig {

/**
* The default principal query
*/
@ConfigItem(name = ConfigItem.PARENT)
public PrincipalQueryConfig defaultPrincipalQuery;
@WithParentName
PrincipalQueryConfig defaultPrincipalQuery();

/**
* Additional principal queries
*/
@ConfigItem(name = ConfigItem.PARENT)
public Map<String, PrincipalQueryConfig> namedPrincipalQueries;
@WithParentName
Map<String, PrincipalQueryConfig> namedPrincipalQueries();

@Override
public String toString() {
return "PrincipalQueriesConfig{" +
"defaultPrincipalQuery=" + defaultPrincipalQuery +
", namedPrincipalQueries=" + namedPrincipalQueries +
'}';
}
String toString();
}
Loading

0 comments on commit 9678bc5

Please sign in to comment.