github-code-scanning[bot] commented on code in PR #355: URL: https://github.com/apache/syncope/pull/355#discussion_r905006953
########## common/am/lib/src/main/java/org/apache/syncope/common/lib/attr/JDBCAttrRepoConf.java: ########## @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.syncope.common.lib.attr; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.syncope.common.lib.AbstractJDBCConf; + +public class JDBCAttrRepoConf extends AbstractJDBCConf implements AttrRepoConf { + + private static final long serialVersionUID = -4474060002361453868L; + + public enum CaseCanonicalizationMode { + + LOWER, + UPPER, + NONE; + + } + + public enum QueryType { + AND, + OR + + } + + /** + * Designed to work against a table where there is a mapping of one row to one user. + */ + private boolean singleRow = true; + + /** + * If the SQL should only be run if all attributes listed in the mappings exist in the query. + */ + private boolean requireAllAttributes = true; + + /** + * When constructing the final person object from the attribute repository, + * indicate how the username should be canonicalized. + */ + private CaseCanonicalizationMode caseCanonicalization = CaseCanonicalizationMode.NONE; + + /** + * Indicates how multiple attributes in a query should be concatenated together. + */ + private QueryType queryType = QueryType.AND; + + /** + * Used only when there is a mapping of many rows to one user. + * This is done using a key-value structure where the key is the + * name of the "attribute name" column the value is the name of the "attribute value" column. + */ + private final Map<String, String> columnMappings = new HashMap<>(0); + + /** + * Username attribute(s) to use when running the SQL query. + */ + private final List<String> username = new ArrayList<>(0); + + /** + * Map of attributes to fetch from the database. + * Attributes are defined using a key-value structure + * where CAS allows the attribute name/key to be renamed virtually + * to a different attribute. The key is the attribute fetched + * from the data source and the value is the attribute name CAS should + * use for virtual renames. + */ + private final Map<String, String> attributes = new HashMap<>(0); + + /** + * Collection of attributes, used to build the SQL query, that should go through + * a case canonicalization process defined as {@code key->value}. + */ + private final List<String> caseInsensitiveQueryAttributes = new ArrayList<>(0); + + /** + * Define a {@code Map} of query attribute names to data-layer attribute names to use when building the query. + * The key is always the name of the query attribute that is defined by CAS and passed internally, + * and the value is the database column that should map. + */ + private final Map<String, String> queryAttributes = new HashMap<>(0); + + public boolean isSingleRow() { + return singleRow; + } + + public void setSingleRow(final boolean singleRow) { + this.singleRow = singleRow; + } + + public boolean isRequireAllAttributes() { + return requireAllAttributes; + } + + public void setRequireAllAttributes(final boolean requireAllAttributes) { + this.requireAllAttributes = requireAllAttributes; + } + + public CaseCanonicalizationMode getCaseCanonicalization() { + return caseCanonicalization; + } + + public void setCaseCanonicalization(final CaseCanonicalizationMode caseCanonicalization) { + this.caseCanonicalization = caseCanonicalization; + } + + public QueryType getQueryType() { + return queryType; + } + + public void setQueryType(final QueryType queryType) { + this.queryType = queryType; + } + + public Map<String, String> getColumnMappings() { + return columnMappings; + } + + public List<String> getUsername() { + return username; + } + + public Map<String, String> getAttributes() { + return attributes; + } + + public List<String> getCaseInsensitiveQueryAttributes() { + return caseInsensitiveQueryAttributes; + } + + public Map<String, String> getQueryAttributes() { Review Comment: ## Exposing internal representation getQueryAttributes exposes the internal representation stored in field queryAttributes. The value may be modified [after this call to getQueryAttributes](1). [Show more details](https://github.com/apache/syncope/security/code-scanning/1055) ########## wa/bootstrap/src/main/java/org/apache/syncope/wa/bootstrap/AuthModulePropertySourceMapper.java: ########## @@ -0,0 +1,264 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.syncope.wa.bootstrap; + +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.auth.AuthModuleConf; +import org.apache.syncope.common.lib.auth.DuoMfaAuthModuleConf; +import org.apache.syncope.common.lib.auth.GoogleMfaAuthModuleConf; +import org.apache.syncope.common.lib.auth.JDBCAuthModuleConf; +import org.apache.syncope.common.lib.auth.JaasAuthModuleConf; +import org.apache.syncope.common.lib.auth.LDAPAuthModuleConf; +import org.apache.syncope.common.lib.auth.OIDCAuthModuleConf; +import org.apache.syncope.common.lib.auth.SAML2IdPAuthModuleConf; +import org.apache.syncope.common.lib.auth.SimpleMfaAuthModuleConf; +import org.apache.syncope.common.lib.auth.StaticAuthModuleConf; +import org.apache.syncope.common.lib.auth.SyncopeAuthModuleConf; +import org.apache.syncope.common.lib.auth.U2FAuthModuleConf; +import org.apache.syncope.common.lib.to.AuthModuleTO; +import org.apache.syncope.common.lib.types.AuthModuleState; +import org.apereo.cas.configuration.CasCoreConfigurationUtils; +import org.apereo.cas.configuration.model.core.authentication.AuthenticationHandlerStates; +import org.apereo.cas.configuration.model.support.generic.AcceptAuthenticationProperties; +import org.apereo.cas.configuration.model.support.jaas.JaasAuthenticationProperties; +import org.apereo.cas.configuration.model.support.jdbc.authn.QueryJdbcAuthenticationProperties; +import org.apereo.cas.configuration.model.support.ldap.AbstractLdapAuthenticationProperties; +import org.apereo.cas.configuration.model.support.ldap.LdapAuthenticationProperties; +import org.apereo.cas.configuration.model.support.mfa.DuoSecurityMultifactorAuthenticationProperties; +import org.apereo.cas.configuration.model.support.mfa.gauth.GoogleAuthenticatorMultifactorProperties; +import org.apereo.cas.configuration.model.support.mfa.gauth.LdapGoogleAuthenticatorMultifactorProperties; +import org.apereo.cas.configuration.model.support.mfa.simple.CasSimpleMultifactorAuthenticationProperties; +import org.apereo.cas.configuration.model.support.mfa.u2f.U2FMultifactorAuthenticationProperties; +import org.apereo.cas.configuration.model.support.pac4j.oidc.Pac4jGenericOidcClientProperties; +import org.apereo.cas.configuration.model.support.pac4j.oidc.Pac4jOidcClientProperties; +import org.apereo.cas.configuration.model.support.pac4j.saml.Pac4jSamlClientProperties; +import org.apereo.cas.configuration.model.support.syncope.SyncopeAuthenticationProperties; +import org.apereo.cas.util.ResourceUtils; +import org.apereo.cas.util.model.TriStateBoolean; + +public class AuthModulePropertySourceMapper extends PropertySourceMapper implements AuthModuleConf.Mapper { + + protected final String syncopeClientAddress; + + protected final AuthModuleTO authModuleTO; + + public AuthModulePropertySourceMapper(final String syncopeClientAddress, final AuthModuleTO attrRepoTO) { + this.syncopeClientAddress = syncopeClientAddress; + this.authModuleTO = attrRepoTO; + } + + @Override + public Map<String, Object> map(final StaticAuthModuleConf conf) { + AcceptAuthenticationProperties props = new AcceptAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setState(AuthenticationHandlerStates.valueOf(authModuleTO.getState().name())); + props.setOrder(authModuleTO.getOrder()); + String users = conf.getUsers().entrySet().stream(). + map(entry -> entry.getKey() + "::" + entry.getValue()). + collect(Collectors.joining(",")); + props.setUsers(users); + + return prefix("cas.authn.accept.", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final LDAPAuthModuleConf conf) { + LdapAuthenticationProperties props = new LdapAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setState(AuthenticationHandlerStates.valueOf(authModuleTO.getState().name())); + props.setOrder(authModuleTO.getOrder()); + if (StringUtils.isNotBlank(conf.getBindDn()) && StringUtils.isNotBlank(conf.getBindCredential())) { + props.setType(AbstractLdapAuthenticationProperties.AuthenticationTypes.AUTHENTICATED); + } + props.setPrincipalAttributeId(conf.getUserIdAttribute()); + props.setPrincipalAttributeList(conf.getPrincipalAttributeList()); + fill(props, conf); + + return prefix("cas.authn.ldap[].", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final JDBCAuthModuleConf conf) { + QueryJdbcAuthenticationProperties props = new QueryJdbcAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setState(AuthenticationHandlerStates.valueOf(authModuleTO.getState().name())); + props.setOrder(authModuleTO.getOrder()); + props.setSql(conf.getSql()); + props.setFieldDisabled(conf.getFieldDisabled()); + props.setFieldExpired(conf.getFieldExpired()); + props.setFieldPassword(conf.getFieldPassword()); + props.setPrincipalAttributeList(conf.getPrincipalAttributeList()); + fill(props, conf); + + return prefix("cas.authn.jdbc.query[].", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final JaasAuthModuleConf conf) { + JaasAuthenticationProperties props = new JaasAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setState(AuthenticationHandlerStates.valueOf(authModuleTO.getState().name())); + props.setOrder(authModuleTO.getOrder()); + props.setLoginConfigType(conf.getLoginConfigType()); + props.setKerberosKdcSystemProperty(conf.getKerberosKdcSystemProperty()); + props.setKerberosRealmSystemProperty(conf.getKerberosRealmSystemProperty()); + props.setLoginConfigType(conf.getLoginConfigurationFile()); + props.setRealm(conf.getRealm()); + + return prefix("cas.authn.jaas[].", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final OIDCAuthModuleConf conf) { + Pac4jGenericOidcClientProperties props = new Pac4jGenericOidcClientProperties(); + props.setId(conf.getId()); + props.setEnabled(authModuleTO.getState() == AuthModuleState.ACTIVE); + props.setCustomParams(conf.getCustomParams()); + props.setDiscoveryUri(conf.getDiscoveryUri()); + props.setMaxClockSkew(conf.getMaxClockSkew()); + props.setClientName(authModuleTO.getKey()); + props.setPreferredJwsAlgorithm(conf.getPreferredJwsAlgorithm()); + props.setResponseMode(conf.getResponseMode()); + props.setResponseType(conf.getResponseType()); + props.setScope(conf.getScope()); + props.setSecret(conf.getSecret()); + props.setPrincipalAttributeId(conf.getUserIdAttribute()); + Pac4jOidcClientProperties client = new Pac4jOidcClientProperties(); + client.setGeneric(props); + + return prefix("cas.authn.pac4j.oidc[].generic.", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final SAML2IdPAuthModuleConf conf) { + Pac4jSamlClientProperties props = new Pac4jSamlClientProperties(); + props.setClientName(authModuleTO.getKey()); + props.setEnabled(authModuleTO.getState() == AuthModuleState.ACTIVE); + props.setAcceptedSkew(conf.getAcceptedSkew()); + props.setAssertionConsumerServiceIndex(conf.getAssertionConsumerServiceIndex()); + props.setAttributeConsumingServiceIndex(conf.getAttributeConsumingServiceIndex()); + props.setAuthnContextClassRef(conf.getAuthnContextClassRefs()); + props.setAuthnContextComparisonType(conf.getAuthnContextComparisonType()); + props.setBlockedSignatureSigningAlgorithms(conf.getBlockedSignatureSigningAlgorithms()); + props.setDestinationBinding(conf.getDestinationBinding().getUri()); + props.setIdentityProviderMetadataPath(conf.getIdentityProviderMetadataPath()); + props.setKeystoreAlias(conf.getKeystoreAlias()); + props.setKeystorePassword(conf.getKeystorePassword()); + props.setMaximumAuthenticationLifetime(conf.getMaximumAuthenticationLifetime()); + props.setNameIdPolicyFormat(conf.getNameIdPolicyFormat()); + props.setPrivateKeyPassword(conf.getPrivateKeyPassword()); + props.setProviderName(conf.getProviderName()); + props.setServiceProviderEntityId(conf.getServiceProviderEntityId()); + props.setSignatureAlgorithms(conf.getSignatureAlgorithms()); + props.setSignatureCanonicalizationAlgorithm(conf.getSignatureCanonicalizationAlgorithm()); + props.setSignatureReferenceDigestMethods(conf.getSignatureReferenceDigestMethods()); + props.setPrincipalAttributeId(conf.getUserIdAttribute()); + props.setNameIdPolicyAllowCreate(StringUtils.isBlank(conf.getNameIdPolicyAllowCreate()) + ? TriStateBoolean.UNDEFINED + : TriStateBoolean.valueOf(conf.getNameIdPolicyAllowCreate().toUpperCase())); + + return prefix("cas.authn.pac4j.saml[].", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final SyncopeAuthModuleConf conf) { + SyncopeAuthenticationProperties props = new SyncopeAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setState(AuthenticationHandlerStates.valueOf(authModuleTO.getState().name())); + props.setDomain(conf.getDomain()); + props.setUrl(StringUtils.substringBefore(syncopeClientAddress, "/rest")); + + return prefix("cas.authn.syncope.", CasCoreConfigurationUtils.asMap(props)); + } + + @Override + public Map<String, Object> map(final GoogleMfaAuthModuleConf conf) { + GoogleAuthenticatorMultifactorProperties props = new GoogleAuthenticatorMultifactorProperties(); + props.setName(authModuleTO.getKey()); + props.setOrder(authModuleTO.getOrder()); + props.getCore().setIssuer(conf.getIssuer()); + props.getCore().setCodeDigits(conf.getCodeDigits()); + props.getCore().setLabel(conf.getLabel()); + props.getCore().setTimeStepSize(conf.getTimeStepSize()); + props.getCore().setWindowSize(conf.getWindowSize()); + + if (conf.getLdap() != null) { + LdapGoogleAuthenticatorMultifactorProperties ldapProps = new LdapGoogleAuthenticatorMultifactorProperties(); + ldapProps.setAccountAttributeName(conf.getLdap().getAccountAttributeName()); + fill(ldapProps, conf.getLdap()); + props.setLdap(ldapProps); + } + + return prefix("cas.authn.mfa.gauth.", CasCoreConfigurationUtils.asMap(props)); + } + + @SuppressWarnings("deprecation") + @Override + public Map<String, Object> map(final DuoMfaAuthModuleConf conf) { + DuoSecurityMultifactorAuthenticationProperties props = new DuoSecurityMultifactorAuthenticationProperties(); + props.setName(authModuleTO.getKey()); + props.setOrder(authModuleTO.getOrder()); + props.setDuoApiHost(conf.getApiHost()); + props.setDuoApplicationKey(conf.getApplicationKey()); Review Comment: ## Deprecated method or constructor invocation Invoking [DuoSecurityMultifactorAuthenticationProperties.setDuoApplicationKey](1) should be avoided because it has been deprecated. [Show more details](https://github.com/apache/syncope/security/code-scanning/1054) ########## common/am/lib/src/main/java/org/apache/syncope/common/lib/attr/StubAttrRepoConf.java: ########## @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.syncope.common.lib.attr; + +import java.util.HashMap; +import java.util.Map; + +public class StubAttrRepoConf implements AttrRepoConf { + + private static final long serialVersionUID = 835890230066546723L; + + /** + * Static attributes that need to be mapped to a hardcoded value belong here. + * The structure follows a key-value pair where key is the attribute name + * and value is the attribute value. + */ + private final Map<String, String> attributes = new HashMap<>(0); + + public Map<String, String> getAttributes() { Review Comment: ## Exposing internal representation getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](1). getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](2). getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](3). getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](4). getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](5). getAttributes exposes the internal representation stored in field attributes. The value may be modified [after this call to getAttributes](6). [Show more details](https://github.com/apache/syncope/security/code-scanning/1056) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
