mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-10117: Account ldap binding (#2381)
Map an ldap group to an account. Ldap related settings on a domain level.
This commit is contained in:
parent
1d0f2128f6
commit
45df928e04
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.admin.config;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -77,6 +78,12 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||
description = "the ID of the Account to update the parameter value for corresponding account")
|
||||
private Long accountId;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = DomainResponse.class,
|
||||
description = "the ID of the Domain to update the parameter value for corresponding domain")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ImageStoreResponse.class,
|
||||
|
|
@ -111,6 +118,10 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||
return accountId;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getImageStoreId() {
|
||||
return imageStoreId;
|
||||
}
|
||||
|
|
@ -158,6 +169,9 @@ public class ListCfgsByCmd extends BaseListCmd {
|
|||
if (getAccountId() != null) {
|
||||
cfgResponse.setScope("account");
|
||||
}
|
||||
if (getDomainId() != null) {
|
||||
cfgResponse.setScope("domain");
|
||||
}
|
||||
if (getImageStoreId() != null){
|
||||
cfgResponse.setScope("imagestore");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package org.apache.cloudstack.api.command.admin.config;
|
|||
|
||||
import com.google.common.base.Strings;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiArgValidator;
|
||||
|
|
@ -76,6 +77,12 @@ public class UpdateCfgCmd extends BaseCmd {
|
|||
description = "the ID of the Account to update the parameter value for corresponding account")
|
||||
private Long accountId;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = DomainResponse.class,
|
||||
description = "the ID of the Domain to update the parameter value for corresponding domain")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.IMAGE_STORE_UUID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ImageStoreResponse.class,
|
||||
|
|
@ -115,6 +122,10 @@ public class UpdateCfgCmd extends BaseCmd {
|
|||
return accountId;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getImageStoreId() {
|
||||
return imageStoreId;
|
||||
}
|
||||
|
|
@ -157,6 +168,9 @@ public class UpdateCfgCmd extends BaseCmd {
|
|||
if (getAccountId() != null) {
|
||||
response.setScope("account");
|
||||
}
|
||||
if (getDomainId() != null) {
|
||||
response.setScope("domain");
|
||||
}
|
||||
response.setValue(value);
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@
|
|||
<bean id="engineDcDetailsDaoImpl" class="org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl" />
|
||||
<bean id="diskOfferingJoinDaoImpl" class="com.cloud.api.query.dao.DiskOfferingJoinDaoImpl" />
|
||||
<bean id="domainDaoImpl" class="com.cloud.domain.dao.DomainDaoImpl" />
|
||||
<bean id="domainDetailsDaoImpl" class="com.cloud.domain.dao.DomainDetailsDaoImpl" />
|
||||
<bean id="domainJoinDaoImpl" class="com.cloud.api.query.dao.DomainJoinDaoImpl" />
|
||||
<bean id="domainRouterDaoImpl" class="com.cloud.vm.dao.DomainRouterDaoImpl" />
|
||||
<bean id="domainRouterJoinDaoImpl" class="com.cloud.api.query.dao.DomainRouterJoinDaoImpl" />
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ CREATE VIEW `cloud`.`volume_view` AS
|
|||
`cloud`.`domain` resource_tag_domain ON resource_tag_domain.id = resource_tags.domain_id;
|
||||
|
||||
-- Extra Dhcp Options
|
||||
CREATE TABLE `cloud`.`nic_extra_dhcp_options` (
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`nic_extra_dhcp_options` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
`uuid` varchar(255) UNIQUE,
|
||||
`nic_id` bigint unsigned NOT NULL COMMENT ' nic id where dhcp options are applied',
|
||||
|
|
@ -523,3 +523,20 @@ ADD COLUMN `forsystemvms` TINYINT(1) NOT NULL DEFAULT '0' COMMENT 'Indicates if
|
|||
|
||||
ALTER TABLE `cloud`.`op_dc_ip_address_alloc`
|
||||
ADD COLUMN `vlan` INT(10) UNSIGNED NULL COMMENT 'Vlan the management network range is on';
|
||||
|
||||
-- ldap binding on domain level
|
||||
CREATE TABLE IF NOT EXISTS `cloud`.`domain_details` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`domain_id` bigint unsigned NOT NULL COMMENT 'account id',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`value` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_domain_details__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE
|
||||
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE cloud.ldap_configuration ADD COLUMN domain_id BIGINT(20) DEFAULT NULL;
|
||||
ALTER TABLE cloud.ldap_trust_map ADD COLUMN account_id BIGINT(20) DEFAULT 0;
|
||||
ALTER TABLE cloud.ldap_trust_map DROP FOREIGN KEY fk_ldap_trust_map__domain_id;
|
||||
DROP INDEX uk_ldap_trust_map__domain_id ON cloud.ldap_trust_map;
|
||||
CREATE UNIQUE INDEX uk_ldap_trust_map__bind_location ON ldap_trust_map (domain_id, account_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
// 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 com.cloud.domain;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.cloud.utils.db.Encrypt;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
@Entity
|
||||
@Table(name = "domain_details")
|
||||
public class DomainDetailVO implements InternalIdentity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private long domainId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Encrypt
|
||||
@Column(name = "value")
|
||||
private String value;
|
||||
|
||||
protected DomainDetailVO() {
|
||||
}
|
||||
|
||||
public DomainDetailVO(long domainId, String name, String value) {
|
||||
this.domainId = domainId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
// 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 com.cloud.domain.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface DomainDetailsDao extends GenericDao<DomainDetailVO, Long> {
|
||||
Map<String, String> findDetails(long domainId);
|
||||
|
||||
void persist(long domainId, Map<String, String> details);
|
||||
|
||||
DomainDetailVO findDetail(long domainId, String name);
|
||||
|
||||
void deleteDetails(long domainId);
|
||||
|
||||
void update(long domainId, Map<String, String> details);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// 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 com.cloud.domain.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
|
||||
import org.apache.cloudstack.framework.config.ScopedConfigStorage;
|
||||
|
||||
public class DomainDetailsDaoImpl extends GenericDaoBase<DomainDetailVO, Long> implements DomainDetailsDao, ScopedConfigStorage {
|
||||
protected final SearchBuilder<DomainDetailVO> domainSearch;
|
||||
|
||||
protected DomainDetailsDaoImpl() {
|
||||
domainSearch = createSearchBuilder();
|
||||
domainSearch.and("domainId", domainSearch.entity().getDomainId(), Op.EQ);
|
||||
domainSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long domainId) {
|
||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
||||
List<DomainDetailVO> results = sc.list();
|
||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||
for (DomainDetailVO r : results) {
|
||||
details.put(r.getName(), r.getValue());
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist(long domainId, Map<String, String> details) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<DomainDetailVO> sc = domainSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
expunge(sc);
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
DomainDetailVO vo = new DomainDetailVO(domainId, detail.getKey(), detail.getValue());
|
||||
persist(vo);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomainDetailVO findDetail(long domainId, String name) {
|
||||
QueryBuilder<DomainDetailVO> sc = QueryBuilder.create(DomainDetailVO.class);
|
||||
sc.and(sc.entity().getDomainId(), Op.EQ, domainId);
|
||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long domainId) {
|
||||
SearchCriteria<DomainDetailVO> sc = domainSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
List<DomainDetailVO> results = search(sc, null);
|
||||
for (DomainDetailVO result : results) {
|
||||
remove(result.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(long domainId, Map<String, String> details) {
|
||||
Map<String, String> oldDetails = findDetails(domainId);
|
||||
oldDetails.putAll(details);
|
||||
persist(domainId, oldDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Scope getScope() {
|
||||
return Scope.Domain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigValue(long id, ConfigKey<?> key) {
|
||||
DomainDetailVO vo = findDetail(id, key.key());
|
||||
return vo == null ? null : vo.getValue();
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
|||
public class ConfigKey<T> {
|
||||
|
||||
public static enum Scope {
|
||||
Global, Zone, Cluster, StoragePool, Account, ManagementServer, ImageStore
|
||||
Global, Zone, Cluster, StoragePool, Account, ManagementServer, ImageStore, Domain
|
||||
}
|
||||
|
||||
private final String _category;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
|
|||
_scopeLevelConfigsMap.put(ConfigKey.Scope.StoragePool, new HashSet<ConfigKey<?>>());
|
||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.Account, new HashSet<ConfigKey<?>>());
|
||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.ImageStore, new HashSet<ConfigKey<?>>());
|
||||
_scopeLevelConfigsMap.put(ConfigKey.Scope.Domain, new HashSet<ConfigKey<?>>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ import com.cloud.deploy.DeploymentPlanner;
|
|||
import com.cloud.deploy.DeploymentPlanningManager;
|
||||
import com.cloud.deploy.dao.PlannerHostReservationDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDetailsDaoImpl;
|
||||
import com.cloud.event.dao.EventDaoImpl;
|
||||
import com.cloud.event.dao.EventJoinDaoImpl;
|
||||
import com.cloud.event.dao.UsageEventDaoImpl;
|
||||
|
|
@ -148,8 +149,8 @@ import com.cloud.host.dao.HostDaoImpl;
|
|||
import com.cloud.host.dao.HostDetailsDaoImpl;
|
||||
import com.cloud.host.dao.HostTagsDaoImpl;
|
||||
import com.cloud.hypervisor.HypervisorGuruManagerImpl;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl;
|
||||
import com.cloud.hypervisor.XenServerGuru;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl;
|
||||
import com.cloud.network.ExternalDeviceUsageManager;
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.IpAddressManagerImpl;
|
||||
|
|
@ -169,8 +170,8 @@ import com.cloud.network.as.dao.CounterDaoImpl;
|
|||
import com.cloud.network.dao.AccountGuestVlanMapDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesDaoImpl;
|
||||
import com.cloud.network.dao.IPAddressDaoImpl;
|
||||
import com.cloud.network.dao.IPAddressDao;
|
||||
import com.cloud.network.dao.IPAddressDaoImpl;
|
||||
import com.cloud.network.dao.LBHealthCheckPolicyDaoImpl;
|
||||
import com.cloud.network.dao.LBStickinessPolicyDaoImpl;
|
||||
import com.cloud.network.dao.LoadBalancerDaoImpl;
|
||||
|
|
@ -308,7 +309,7 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
|
|||
ConditionDaoImpl.class, ConfigurationDaoImpl.class, ConfigurationManagerImpl.class, ConfigurationServerImpl.class, ConsoleProxyDaoImpl.class,
|
||||
ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterDetailsDaoImpl.class, DataCenterIpAddressDaoImpl.class,
|
||||
DataCenterJoinDaoImpl.class, DataCenterLinkLocalIpAddressDaoImpl.class, DataCenterVnetDaoImpl.class, DcDetailsDaoImpl.class, DedicatedResourceDaoImpl.class,
|
||||
DiskOfferingDaoImpl.class, DiskOfferingJoinDaoImpl.class, DomainDaoImpl.class, DomainManagerImpl.class, DomainRouterDaoImpl.class, DomainRouterJoinDaoImpl.class,
|
||||
DiskOfferingDaoImpl.class, DiskOfferingJoinDaoImpl.class, DomainDaoImpl.class, DomainDetailsDaoImpl.class, DomainManagerImpl.class, DomainRouterDaoImpl.class, DomainRouterJoinDaoImpl.class,
|
||||
EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, ExtensionRegistry.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class,
|
||||
FirewallRulesDaoImpl.class, GuestOSCategoryDaoImpl.class, GuestOSDaoImpl.class, HostDaoImpl.class, HostDetailsDaoImpl.class, HostJoinDaoImpl.class,
|
||||
HostPodDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, HypervisorCapabilitiesDaoImpl.class, HypervisorGuruManagerImpl.class,
|
||||
|
|
|
|||
|
|
@ -317,7 +317,13 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
@Override
|
||||
public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveUser(long id, Long domainId, long accountId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@
|
|||
<configuration>
|
||||
<sources>
|
||||
<fileset>
|
||||
<directory>test/groovy</directory>
|
||||
<directory>test</directory>
|
||||
<includes>
|
||||
<include>**/*.groovy</include>
|
||||
<include>groovy/**/*.groovy</include>
|
||||
</includes>
|
||||
</fileset>
|
||||
</sources>
|
||||
|
|
@ -70,7 +70,8 @@
|
|||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Spec*</include>
|
||||
<include>**/*Spec.groovy</include>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
@ -90,6 +91,7 @@
|
|||
</plugin>
|
||||
|
||||
</plugins>
|
||||
<testSourceDirectory>test</testSourceDirectory>
|
||||
</build>
|
||||
<dependencies>
|
||||
<!-- Mandatory dependencies for using Spock -->
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import com.cloud.utils.Pair;
|
|||
* @deprecated as of 4.3 use the new api {@link LdapAddConfigurationCmd}
|
||||
*/
|
||||
@Deprecated
|
||||
@APICommand(name = "ldapConfig", description = "Configure the LDAP context for this site.", responseObject = LDAPConfigResponse.class, since = "3.0.0",
|
||||
@APICommand(name = "ldapConfig", description = "(Deprecated, use addLdapConfiguration) Configure the LDAP context for this site.", responseObject = LDAPConfigResponse.class, since = "3.0.0",
|
||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
|
||||
|
||||
public class LDAPConfigCmd extends BaseCmd {
|
||||
|
|
@ -190,8 +190,8 @@ public class LDAPConfigCmd extends BaseCmd {
|
|||
|
||||
if (result.second() > 0) {
|
||||
boolean useSSlConfig = _ldapConfiguration.getSSLStatus();
|
||||
String searchBaseConfig = _ldapConfiguration.getBaseDn();
|
||||
String bindDnConfig = _ldapConfiguration.getBindPrincipal();
|
||||
String searchBaseConfig = _ldapConfiguration.getBaseDn(null);
|
||||
String bindDnConfig = _ldapConfiguration.getBindPrincipal(null);
|
||||
for (LdapConfigurationVO ldapConfigurationVO : result.first()) {
|
||||
responses.add(createLDAPConfigResponse(ldapConfigurationVO.getHostname(), ldapConfigurationVO.getPort(), useSSlConfig, null, searchBaseConfig,
|
||||
bindDnConfig));
|
||||
|
|
@ -226,7 +226,7 @@ public class LDAPConfigCmd extends BaseCmd {
|
|||
}
|
||||
|
||||
private boolean updateLDAP() {
|
||||
_ldapManager.addConfiguration(hostname, port);
|
||||
_ldapManager.addConfiguration(hostname, port, null);
|
||||
|
||||
/**
|
||||
* There is no query filter now. It is derived from ldap.user.object and ldap.search.group.principle
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ import com.cloud.utils.Pair;
|
|||
* @deprecated as of 4.3 use the new api {@link LdapDeleteConfigurationCmd}
|
||||
*/
|
||||
@Deprecated
|
||||
@APICommand(name = "ldapRemove", description = "Remove the LDAP context for this site.", responseObject = LDAPConfigResponse.class, since = "3.0.1",
|
||||
@APICommand(name = "ldapRemove", description = "(Deprecated , use deleteLdapConfiguration) Remove the LDAP context for this site.", responseObject = LDAPConfigResponse.class, since = "3.0.1",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class LDAPRemoveCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(LDAPRemoveCmd.class.getName());
|
||||
|
|
@ -60,7 +60,7 @@ public class LDAPRemoveCmd extends BaseCmd {
|
|||
LdapListConfigurationCmd listConfigurationCmd = new LdapListConfigurationCmd(_ldapManager);
|
||||
Pair<List<? extends LdapConfigurationVO>, Integer> result = _ldapManager.listConfigurations(listConfigurationCmd);
|
||||
for (LdapConfigurationVO config : result.first()) {
|
||||
_ldapManager.deleteConfiguration(config.getHostname());
|
||||
_ldapManager.deleteConfiguration(config.getHostname(), 0, null);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.cloudstack.api.command;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -40,12 +42,15 @@ public class LdapAddConfigurationCmd extends BaseCmd {
|
|||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
@Parameter(name = "hostname", type = CommandType.STRING, required = true, description = "Hostname")
|
||||
@Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "Hostname")
|
||||
private String hostname;
|
||||
|
||||
@Parameter(name = "port", type = CommandType.INTEGER, required = true, description = "Port")
|
||||
@Parameter(name = ApiConstants.PORT, type = CommandType.INTEGER, required = true, description = "Port")
|
||||
private int port;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = false, entityType = DomainResponse.class, description = "linked domain")
|
||||
private Long domainId;
|
||||
|
||||
public LdapAddConfigurationCmd() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -58,7 +63,7 @@ public class LdapAddConfigurationCmd extends BaseCmd {
|
|||
@Override
|
||||
public void execute() throws ServerApiException {
|
||||
try {
|
||||
final LdapConfigurationResponse response = _ldapManager.addConfiguration(hostname, port);
|
||||
final LdapConfigurationResponse response = _ldapManager.addConfiguration(hostname, port, domainId);
|
||||
response.setObjectName("LdapAddConfiguration");
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
|
@ -86,6 +91,10 @@ public class LdapAddConfigurationCmd extends BaseCmd {
|
|||
return port;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setHostname(final String hostname) {
|
||||
this.hostname = hostname;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ public class LdapCreateAccountCmd extends BaseCmd {
|
|||
Long finalDomainId = getDomainId();
|
||||
callContext.setEventDetails("Account Name: " + finalAccountName + ", Domain Id:" + finalDomainId);
|
||||
try {
|
||||
final LdapUser user = _ldapManager.getUser(username);
|
||||
final LdapUser user = _ldapManager.getUser(username, domainId);
|
||||
validateUser(user);
|
||||
final UserAccount userAccount = createCloudstackUserAccount(user, finalAccountName, finalDomainId);
|
||||
if (userAccount != null) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.cloudstack.api.command;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -40,9 +42,16 @@ public class LdapDeleteConfigurationCmd extends BaseCmd {
|
|||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
@Parameter(name = "hostname", type = CommandType.STRING, required = true, description = "Hostname")
|
||||
|
||||
@Parameter(name = ApiConstants.HOST_NAME, type = CommandType.STRING, required = true, description = "Hostname")
|
||||
private String hostname;
|
||||
|
||||
@Parameter(name = ApiConstants.PORT, type = CommandType.INTEGER, required = false, description = "port")
|
||||
private int port;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = false, entityType = DomainResponse.class, description = "linked domain")
|
||||
private Long domainId;
|
||||
|
||||
public LdapDeleteConfigurationCmd() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -52,10 +61,22 @@ public class LdapDeleteConfigurationCmd extends BaseCmd {
|
|||
_ldapManager = ldapManager;
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ServerApiException {
|
||||
try {
|
||||
final LdapConfigurationResponse response = _ldapManager.deleteConfiguration(hostname);
|
||||
final LdapConfigurationResponse response = _ldapManager.deleteConfiguration(this);
|
||||
response.setObjectName("LdapDeleteConfiguration");
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
|
|
|||
|
|
@ -142,9 +142,9 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
|||
try {
|
||||
if (StringUtils.isNotBlank(groupName)) {
|
||||
|
||||
users = _ldapManager.getUsersInGroup(groupName);
|
||||
users = _ldapManager.getUsersInGroup(groupName, domainId);
|
||||
} else {
|
||||
users = _ldapManager.getUsers();
|
||||
users = _ldapManager.getUsers(domainId);
|
||||
}
|
||||
} catch (NoLdapUserMatchingQueryException ex) {
|
||||
users = new ArrayList<LdapUser>();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import java.util.List;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
|
|
@ -44,12 +46,15 @@ public class LdapListConfigurationCmd extends BaseListCmd {
|
|||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
@Parameter(name = "hostname", type = CommandType.STRING, required = false, description = "Hostname")
|
||||
@Parameter(name = ApiConstants. HOST_NAME, type = CommandType.STRING, required = false, description = "Hostname")
|
||||
private String hostname;
|
||||
|
||||
@Parameter(name = "port", type = CommandType.INTEGER, required = false, description = "Port")
|
||||
@Parameter(name = ApiConstants.PORT, type = CommandType.INTEGER, required = false, description = "Port")
|
||||
private int port;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = false, entityType = DomainResponse.class, description = "linked domain")
|
||||
private Long domainId;
|
||||
|
||||
public LdapListConfigurationCmd() {
|
||||
super();
|
||||
}
|
||||
|
|
@ -97,6 +102,10 @@ public class LdapListConfigurationCmd extends BaseListCmd {
|
|||
return port;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setHostname(final String hostname) {
|
||||
this.hostname = hostname;
|
||||
}
|
||||
|
|
@ -104,4 +113,8 @@ public class LdapListConfigurationCmd extends BaseListCmd {
|
|||
public void setPort(final int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setDomainId(final Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class LdapListUsersCmd extends BaseListCmd {
|
|||
List<LdapUserResponse> ldapResponses = null;
|
||||
final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
|
||||
try {
|
||||
final List<LdapUser> users = _ldapManager.getUsers();
|
||||
final List<LdapUser> users = _ldapManager.getUsers(null);
|
||||
ldapResponses = createLdapUserResponse(users);
|
||||
} catch (final NoLdapUserMatchingQueryException ex) {
|
||||
ldapResponses = new ArrayList<LdapUserResponse>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* 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.cloudstack.api.command;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.LinkAccountToLdapResponse;
|
||||
import org.apache.cloudstack.api.response.LinkDomainToLdapResponse;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.UUID;
|
||||
|
||||
@APICommand(name = LinkAccountToLdapCmd.APINAME, description = "link a cloudstack account to a group or OU in ldap", responseObject = LinkDomainToLdapResponse.class, since = "4.11.0",
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, authorized = {RoleType.Admin,RoleType.DomainAdmin})
|
||||
public class LinkAccountToLdapCmd extends BaseCmd {
|
||||
public static final Logger LOGGER = Logger.getLogger(LinkAccountToLdapCmd.class.getName());
|
||||
public static final String APINAME = "linkAccountToLdap";
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "The id of the domain that is to contain the linked account.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, required = false, description = "type of the ldap name. GROUP or OU, defaults to GROUP")
|
||||
private String type;
|
||||
|
||||
@Parameter(name = ApiConstants.LDAP_DOMAIN, type = CommandType.STRING, required = true, description = "name of the group or OU in LDAP")
|
||||
private String ldapDomain;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "name of the account, it will be created if it does not exist")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.ADMIN, type = CommandType.STRING, required = false, description = "domain admin username in LDAP ")
|
||||
private String admin;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, description = "Type of the account to auto import. Specify 0 for user and 2 for "
|
||||
+ "domain admin")
|
||||
private short accountType;
|
||||
|
||||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
@Override
|
||||
public void execute() throws ServerApiException {
|
||||
try {
|
||||
LinkAccountToLdapResponse response = _ldapManager.linkAccountToLdap(this);
|
||||
if (admin != null) {
|
||||
LdapUser ldapUser = null;
|
||||
try {
|
||||
ldapUser = _ldapManager.getUser(admin, type, ldapDomain, domainId);
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
LOGGER.debug("no ldap user matching username " + admin + " in the given group/ou", e);
|
||||
}
|
||||
if (ldapUser != null && !ldapUser.isDisabled()) {
|
||||
Account account = _accountService.getActiveAccountByName(admin, domainId);
|
||||
if (account == null) {
|
||||
try {
|
||||
UserAccount userAccount = _accountService
|
||||
.createUserAccount(admin, "", ldapUser.getFirstname(), ldapUser.getLastname(), ldapUser.getEmail(), null, admin, Account.ACCOUNT_TYPE_DOMAIN_ADMIN, RoleType.DomainAdmin.getId(), domainId, null, null, UUID.randomUUID().toString(),
|
||||
UUID.randomUUID().toString(), User.Source.LDAP);
|
||||
response.setAdminId(String.valueOf(userAccount.getAccountId()));
|
||||
LOGGER.info("created an account with name " + admin + " in the given domain " + domainId);
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("an exception occurred while creating account with name " + admin + " in domain " + domainId, e);
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("an account with name " + admin + " already exists in the domain " + domainId);
|
||||
}
|
||||
} else {
|
||||
LOGGER.debug("ldap user with username " + admin + " is disabled in the given group/ou");
|
||||
}
|
||||
}
|
||||
response.setObjectName(APINAME);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
} catch (final InvalidParameterValueException e) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getLdapDomain() {
|
||||
return ldapDomain;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
public short getAccountType() {
|
||||
return accountType;
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,10 @@ public class LinkDomainToLdapCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, required = true, description = "type of the ldap name. GROUP or OU")
|
||||
private String type;
|
||||
|
||||
@Parameter(name = ApiConstants.LDAP_DOMAIN, type = CommandType.STRING, required = true, description = "name of the group or OU in LDAP")
|
||||
private String ldapDomain;
|
||||
|
||||
@Deprecated
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "name of the group or OU in LDAP")
|
||||
private String name;
|
||||
|
||||
|
|
@ -67,14 +71,35 @@ public class LinkDomainToLdapCmd extends BaseCmd {
|
|||
@Inject
|
||||
private LdapManager _ldapManager;
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getLdapDomain() {
|
||||
return ldapDomain == null ? name : ldapDomain;
|
||||
}
|
||||
|
||||
public String getAdmin() {
|
||||
return admin;
|
||||
}
|
||||
|
||||
public short getAccountType() {
|
||||
return accountType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute() throws ServerApiException {
|
||||
try {
|
||||
LinkDomainToLdapResponse response = _ldapManager.linkDomainToLdap(domainId, type, name, accountType);
|
||||
LinkDomainToLdapResponse response = _ldapManager.linkDomainToLdap(this);
|
||||
if(admin!=null) {
|
||||
LdapUser ldapUser = null;
|
||||
try {
|
||||
ldapUser = _ldapManager.getUser(admin, type, name);
|
||||
ldapUser = _ldapManager.getUser(admin, type, getLdapDomain(), domainId);
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug("no ldap user matching username " + admin + " in the given group/ou", e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,31 +18,44 @@ package org.apache.cloudstack.api.response;
|
|||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration;
|
||||
|
||||
@EntityReference(value = LdapConfiguration.class)
|
||||
public class LdapConfigurationResponse extends BaseResponse {
|
||||
@SerializedName("hostname")
|
||||
@Param(description = "hostname")
|
||||
@SerializedName(ApiConstants.HOST_NAME)
|
||||
@Param(description = "name of the host running the ldap server")
|
||||
private String hostname;
|
||||
|
||||
@SerializedName("port")
|
||||
@Param(description = "port")
|
||||
@SerializedName(ApiConstants.PORT)
|
||||
@Param(description = "port teh ldap server is running on")
|
||||
private int port;
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "linked domain")
|
||||
private String domainId;
|
||||
|
||||
public LdapConfigurationResponse() {
|
||||
super();
|
||||
}
|
||||
|
||||
public LdapConfigurationResponse(final String hostname) {
|
||||
super();
|
||||
this.hostname = hostname;
|
||||
setHostname(hostname);
|
||||
}
|
||||
|
||||
public LdapConfigurationResponse(final String hostname, final int port) {
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this(hostname);
|
||||
setPort(port);
|
||||
}
|
||||
|
||||
public LdapConfigurationResponse(final String hostname, final int port, final String domainId) {
|
||||
this(hostname, port);
|
||||
setDomainId(domainId);
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
|
|
@ -60,4 +73,12 @@ public class LdapConfigurationResponse extends BaseResponse {
|
|||
public void setPort(final int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public String getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setDomainId(String domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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.cloudstack.api.response;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
|
||||
public class LinkAccountToLdapResponse extends BaseResponse {
|
||||
|
||||
@SerializedName(ApiConstants.DOMAIN_ID)
|
||||
@Param(description = "id of the Domain which is linked to LDAP")
|
||||
private String domainId;
|
||||
|
||||
@SerializedName(ApiConstants.LDAP_DOMAIN)
|
||||
@Param(description = "name of the group or OU in LDAP which is linked to the domain")
|
||||
private String ldapDomain;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "type of the name in LDAP which is linke to the domain")
|
||||
private String type;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_TYPE)
|
||||
@Param(description = "Type of the account to auto import")
|
||||
private short accountType;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT_ID)
|
||||
@Param(description = "Domain Admin accountId that is created")
|
||||
private String adminId;
|
||||
|
||||
@SerializedName(ApiConstants.ACCOUNT)
|
||||
@Param(description = "name of the account")
|
||||
private String accountName;
|
||||
|
||||
|
||||
public LinkAccountToLdapResponse(String domainId, String type, String ldapDomain, short accountType, String adminId, String accountName) {
|
||||
this.domainId = domainId;
|
||||
this.type = type;
|
||||
this.ldapDomain = ldapDomain;
|
||||
this.accountType = accountType;
|
||||
this.adminId = adminId;
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public String getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public String getLdapDomain() {
|
||||
return ldapDomain;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public short getAccountType() {
|
||||
return accountType;
|
||||
}
|
||||
|
||||
public String getAdminId() {
|
||||
return adminId;
|
||||
}
|
||||
|
||||
public void setAdminId(String adminId) {
|
||||
this.adminId = adminId;
|
||||
}
|
||||
}
|
||||
|
|
@ -66,11 +66,6 @@ public class LinkDomainToLdapResponse extends BaseResponse {
|
|||
return ldapDomain == null ? name : ldapDomain;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getName() {
|
||||
return ldapDomain == null ? name : ldapDomain;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,38 +36,38 @@ public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements Ld
|
|||
private static final String MICROSOFT_AD_MEMBERS_FILTER = "memberOf";
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException {
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context, Long domainId) throws NamingException {
|
||||
if (StringUtils.isBlank(groupName)) {
|
||||
throw new IllegalArgumentException("ldap group name cannot be blank");
|
||||
}
|
||||
|
||||
String basedn = _ldapConfiguration.getBaseDn();
|
||||
String basedn = _ldapConfiguration.getBaseDn(domainId);
|
||||
if (StringUtils.isBlank(basedn)) {
|
||||
throw new IllegalArgumentException("ldap basedn is not configured");
|
||||
}
|
||||
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes(domainId));
|
||||
|
||||
NamingEnumeration<SearchResult> results = context.search(basedn, generateADGroupSearchFilter(groupName), searchControls);
|
||||
NamingEnumeration<SearchResult> results = context.search(basedn, generateADGroupSearchFilter(groupName, domainId), searchControls);
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
users.add(createUser(result));
|
||||
users.add(createUser(result, domainId));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
private String generateADGroupSearchFilter(String groupName) {
|
||||
private String generateADGroupSearchFilter(String groupName, Long domainId) {
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject(domainId));
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
String groupCnName = _ldapConfiguration.getCommonNameAttribute() + "=" +groupName + "," + _ldapConfiguration.getBaseDn();
|
||||
memberOfFilter.append("(").append(getMemberOfAttribute()).append("=");
|
||||
String groupCnName = _ldapConfiguration.getCommonNameAttribute() + "=" +groupName + "," + _ldapConfiguration.getBaseDn(domainId);
|
||||
memberOfFilter.append("(").append(getMemberOfAttribute(domainId)).append("=");
|
||||
memberOfFilter.append(groupCnName);
|
||||
memberOfFilter.append(")");
|
||||
|
||||
|
|
@ -94,8 +94,8 @@ public class ADLdapUserManagerImpl extends OpenLdapUserManagerImpl implements Ld
|
|||
return isDisabledUser;
|
||||
}
|
||||
|
||||
protected String getMemberOfAttribute() {
|
||||
if(_ldapConfiguration.isNestedGroupsEnabled()) {
|
||||
protected String getMemberOfAttribute(final Long domainId) {
|
||||
if(_ldapConfiguration.isNestedGroupsEnabled(domainId)) {
|
||||
return MICROSOFT_AD_NESTED_MEMBERS_FILTER;
|
||||
} else {
|
||||
return MICROSOFT_AD_MEMBERS_FILTER;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -56,60 +58,181 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||
|
||||
@Override
|
||||
public Pair<Boolean, ActionOnFailedAuthentication> authenticate(final String username, final String password, final Long domainId, final Map<String, Object[]> requestParameters) {
|
||||
Pair<Boolean, ActionOnFailedAuthentication> rc = new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
|
||||
|
||||
// TODO not allowing an empty password is a policy we shouldn't decide on. A private cloud may well want to allow this.
|
||||
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
|
||||
s_logger.debug("Username or Password cannot be empty");
|
||||
return new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
|
||||
return rc;
|
||||
}
|
||||
|
||||
boolean result = false;
|
||||
ActionOnFailedAuthentication action = null;
|
||||
|
||||
if (_ldapManager.isLdapEnabled()) {
|
||||
final UserAccount user = _userAccountDao.getUserAccount(username, domainId);
|
||||
LdapTrustMapVO ldapTrustMapVO = _ldapManager.getDomainLinkedToLdap(domainId);
|
||||
if(ldapTrustMapVO != null) {
|
||||
try {
|
||||
LdapUser ldapUser = _ldapManager.getUser(username, ldapTrustMapVO.getType().toString(), ldapTrustMapVO.getName());
|
||||
if(!ldapUser.isDisabled()) {
|
||||
result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password);
|
||||
if(result) {
|
||||
if(user == null) {
|
||||
// import user to cloudstack
|
||||
createCloudStackUserAccount(ldapUser, domainId, ldapTrustMapVO.getAccountType());
|
||||
} else {
|
||||
enableUserInCloudStack(user);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//disable user in cloudstack
|
||||
disableUserInCloudStack(user);
|
||||
}
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
List<LdapTrustMapVO> ldapTrustMapVOs = _ldapManager.getDomainLinkage(domainId);
|
||||
if(ldapTrustMapVOs != null && ldapTrustMapVOs.size() > 0) {
|
||||
if(ldapTrustMapVOs.size() == 1 && ldapTrustMapVOs.get(0).getAccountId() == 0) {
|
||||
// We have a single mapping of a domain to an ldap group or ou
|
||||
return authenticate(username, password, domainId, user, ldapTrustMapVOs.get(0));
|
||||
} else {
|
||||
// we are dealing with mapping of accounts in a domain to ldap groups
|
||||
return authenticate(username, password, domainId, user, ldapTrustMapVOs);
|
||||
}
|
||||
|
||||
} else {
|
||||
//domain is not linked to ldap follow normal authentication
|
||||
if(user != null ) {
|
||||
try {
|
||||
LdapUser ldapUser = _ldapManager.getUser(username);
|
||||
if(!ldapUser.isDisabled()) {
|
||||
result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password);
|
||||
} else {
|
||||
s_logger.debug("user with principal "+ ldapUser.getPrincipal() + " is disabled in ldap");
|
||||
}
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result && user != null) {
|
||||
action = ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT;
|
||||
return authenticate(username, password, domainId, user);
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<Boolean, ActionOnFailedAuthentication>(result, action);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user exists in ldap and create in cloudstack if needed.
|
||||
*
|
||||
* @param username login id
|
||||
* @param password pass phrase
|
||||
* @param domainId domain the user is trying to log on to
|
||||
* @param userAccount cloudstack user object
|
||||
* @param ldapTrustMapVOs the trust mappings of accounts in the domain to ldap groups
|
||||
* @return false if the ldap user object does not exist, is not mapped to an account, is mapped to multiple accounts or if authenitication fails
|
||||
*/
|
||||
private Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount userAccount, List<LdapTrustMapVO> ldapTrustMapVOs) {
|
||||
Pair<Boolean, ActionOnFailedAuthentication> rc = new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
|
||||
try {
|
||||
LdapUser ldapUser = _ldapManager.getUser(username, domainId);
|
||||
List<String> memberships = ldapUser.getMemberships();
|
||||
List<String> mappedGroups = getMappedGroups(ldapTrustMapVOs);
|
||||
mappedGroups.retainAll(memberships);
|
||||
// check membership, there must be only one match in this domain
|
||||
if(ldapUser.isDisabled()) {
|
||||
logAndDisable(userAccount, "attempt to log on using disabled ldap user " + userAccount.getUsername(), false);
|
||||
} else if(mappedGroups.size() > 1) {
|
||||
logAndDisable(userAccount, "user '" + username + "' is mapped to more then one account in domain and will be disabled.", false);
|
||||
} else if(mappedGroups.size() < 1) {
|
||||
logAndDisable(userAccount, "user '" + username + "' is not mapped to an account in domain and will be removed.", true);
|
||||
} else {
|
||||
// a valid ldap configured user exists
|
||||
LdapTrustMapVO mapping = _ldapManager.getLinkedLdapGroup(domainId,mappedGroups.get(0));
|
||||
// we could now assert that ldapTrustMapVOs.contains(mapping);
|
||||
// createUser in Account can only be done by account name not by account id
|
||||
String accountName = _accountManager.getAccount(mapping.getAccountId()).getAccountName();
|
||||
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
||||
// for security reasons we keep processing on faulty login attempt to not give a way information on userid existence
|
||||
if (userAccount == null) {
|
||||
// new user that is in ldap; authenticate and create
|
||||
User user = _accountManager.createUser(username, "", ldapUser.getFirstname(), ldapUser.getLastname(), ldapUser.getEmail(), null, accountName,
|
||||
domainId, UUID.randomUUID().toString(), User.Source.LDAP);
|
||||
/* expected error conditions:
|
||||
*
|
||||
* caught in APIServlet: CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user");
|
||||
* caught in APIServlet: CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted");
|
||||
* would have been thrown above: InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user");
|
||||
* we are system user: PermissionDeniedException("Account id : " + account.getId() + " is a system account, can't add a user to it");
|
||||
* serious and must be thrown: CloudRuntimeException("The user " + userName + " already exists in domain " + domainId);
|
||||
* fatal system error and must be thrown: CloudRuntimeException("Failed to encode password");
|
||||
*/
|
||||
userAccount = _accountManager.getUserAccountById(user.getId());
|
||||
} else {
|
||||
// not a new user, check if mapped group has changed
|
||||
if(userAccount.getAccountId() != mapping.getAccountId()) {
|
||||
_accountManager.moveUser(userAccount.getId(),userAccount.getDomainId(),mapping.getAccountId());
|
||||
}
|
||||
// else { the user hasn't changed in ldap, the ldap group stayed the same, hurray, pass, fun thou self a lot of fun }
|
||||
}
|
||||
}
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
disableUserInCloudStack(userAccount);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
private void logAndDisable(UserAccount userAccount, String msg, boolean remove) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info(msg);
|
||||
}
|
||||
if(remove) {
|
||||
removeUserInCloudStack(userAccount);
|
||||
} else {
|
||||
disableUserInCloudStack(userAccount);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getMappedGroups(List<LdapTrustMapVO> ldapTrustMapVOs) {
|
||||
List<String> groups = new ArrayList<>();
|
||||
for (LdapTrustMapVO vo : ldapTrustMapVOs) {
|
||||
groups.add(vo.getName());
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user exists in ldap and create in cloudstack if needed
|
||||
* @param username login id
|
||||
* @param password pass phrase
|
||||
* @param domainId domain the user is trying to log on to
|
||||
* @param user cloudstack user object
|
||||
* @param ldapTrustMapVO the trust mapping for the domain to the ldap group
|
||||
* @return false if the ldap user object does not exist or authenitication fails
|
||||
*/
|
||||
private Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user, LdapTrustMapVO ldapTrustMapVO) {
|
||||
Pair<Boolean, ActionOnFailedAuthentication> rc = new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
|
||||
try {
|
||||
LdapUser ldapUser = _ldapManager.getUser(username, ldapTrustMapVO.getType().toString(), ldapTrustMapVO.getName(), domainId);
|
||||
final short accountType = ldapTrustMapVO.getAccountType();
|
||||
processLdapUser(password, domainId, user, rc, ldapUser, accountType);
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
private void processLdapUser(String password, Long domainId, UserAccount user, Pair<Boolean, ActionOnFailedAuthentication> rc, LdapUser ldapUser, short accountType) {
|
||||
if(!ldapUser.isDisabled()) {
|
||||
rc.first(_ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId));
|
||||
if(rc.first()) {
|
||||
if(user == null) {
|
||||
// import user to cloudstack
|
||||
createCloudStackUserAccount(ldapUser, domainId, accountType);
|
||||
} else {
|
||||
enableUserInCloudStack(user);
|
||||
}
|
||||
} else if(user != null) {
|
||||
rc.second(ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||
}
|
||||
} else {
|
||||
//disable user in cloudstack
|
||||
disableUserInCloudStack(user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if the user is configured both in ldap and in cloudstack.
|
||||
* @param username login id
|
||||
* @param password pass phrase
|
||||
* @param domainId domain the user is trying to log on to
|
||||
* @param user cloudstack user object
|
||||
* @return false if either user object does not exist or authenitication fails
|
||||
*/
|
||||
private Pair<Boolean, ActionOnFailedAuthentication> authenticate(String username, String password, Long domainId, UserAccount user) {
|
||||
boolean result = false;
|
||||
|
||||
if(user != null ) {
|
||||
try {
|
||||
LdapUser ldapUser = _ldapManager.getUser(username, domainId);
|
||||
if(!ldapUser.isDisabled()) {
|
||||
result = _ldapManager.canAuthenticate(ldapUser.getPrincipal(), password, domainId);
|
||||
} else {
|
||||
s_logger.debug("user with principal "+ ldapUser.getPrincipal() + " is disabled in ldap");
|
||||
}
|
||||
} catch (NoLdapUserMatchingQueryException e) {
|
||||
s_logger.debug(e.getMessage());
|
||||
}
|
||||
}
|
||||
return (!result && user != null) ?
|
||||
new Pair<Boolean, ActionOnFailedAuthentication>(false, ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT):
|
||||
new Pair<Boolean, ActionOnFailedAuthentication>(false, null);
|
||||
}
|
||||
|
||||
private void enableUserInCloudStack(UserAccount user) {
|
||||
|
|
@ -131,6 +254,12 @@ public class LdapAuthenticator extends AdapterBase implements UserAuthenticator
|
|||
}
|
||||
}
|
||||
|
||||
private void removeUserInCloudStack(UserAccount user) {
|
||||
if (user != null) {
|
||||
_accountManager.disableUser(user.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(final String password) {
|
||||
return password;
|
||||
|
|
|
|||
|
|
@ -31,75 +31,215 @@ import org.apache.cloudstack.ldap.dao.LdapConfigurationDao;
|
|||
public class LdapConfiguration implements Configurable{
|
||||
private final static String factory = "com.sun.jndi.ldap.LdapCtxFactory";
|
||||
|
||||
private static final ConfigKey<Long> ldapReadTimeout = new ConfigKey<Long>(Long.class, "ldap.read.timeout", "Advanced", "1000",
|
||||
"LDAP connection Timeout in milli sec", true, ConfigKey.Scope.Global, 1l);
|
||||
private static final ConfigKey<Long> ldapReadTimeout = new ConfigKey<Long>(
|
||||
Long.class,
|
||||
"ldap.read.timeout",
|
||||
"Advanced",
|
||||
"1000",
|
||||
"LDAP connection Timeout in milli sec",
|
||||
true,
|
||||
ConfigKey.Scope.Domain,
|
||||
1l);
|
||||
|
||||
private static final ConfigKey<Integer> ldapPageSize = new ConfigKey<Integer>(Integer.class, "ldap.request.page.size", "Advanced", "1000",
|
||||
"page size sent to ldap server on each request to get user", true, ConfigKey.Scope.Global, 1);
|
||||
private static final ConfigKey<String> ldapProvider = new ConfigKey<String>(String.class, "ldap.provider", "Advanced", "openldap", "ldap provider ex:openldap, microsoftad",
|
||||
true, ConfigKey.Scope.Global, null);
|
||||
private static final ConfigKey<Integer> ldapPageSize = new ConfigKey<Integer>(
|
||||
Integer.class,
|
||||
"ldap.request.page.size",
|
||||
"Advanced",
|
||||
"1000",
|
||||
"page size sent to ldap server on each request to get user",
|
||||
true,
|
||||
ConfigKey.Scope.Domain,
|
||||
1);
|
||||
|
||||
private static final ConfigKey<Boolean> ldapEnableNestedGroups = new ConfigKey<Boolean>(Boolean.class, "ldap.nested.groups.enable", "Advanced", "true",
|
||||
"if true, nested groups will also be queried", true, ConfigKey.Scope.Global, null);
|
||||
private static final ConfigKey<Boolean> ldapEnableNestedGroups = new ConfigKey<Boolean>(
|
||||
"Advanced",
|
||||
Boolean.class,
|
||||
"ldap.nested.groups.enable",
|
||||
"true",
|
||||
"if true, nested groups will also be queried",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private static final ConfigKey<String> ldapMemberOfAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.user.memberof.attribute",
|
||||
"memberof",
|
||||
"the reverse membership attibute for group members",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private static final ConfigKey<String> ldapProvider = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.provider",
|
||||
"openldap",
|
||||
"ldap provider ex:openldap, microsoftad",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private static final ConfigKey<String> ldapBaseDn = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.basedn",
|
||||
null,
|
||||
"Sets the basedn for LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private static final ConfigKey<String> ldapBindPassword = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.bind.password",
|
||||
null,
|
||||
"Sets the bind password for LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapBindPrincipal = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.bind.principal",
|
||||
null,
|
||||
"Sets the bind principal for LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapEmailAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.email.attribute",
|
||||
"mail",
|
||||
"Sets the email attribute used within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapFirstnameAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.firstname.attribute",
|
||||
"givenname",
|
||||
"Sets the firstname attribute used within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapLastnameAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class, "ldap.lastname.attribute",
|
||||
"sn",
|
||||
"Sets the lastname attribute used within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapUsernameAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.username.attribute",
|
||||
"uid",
|
||||
"Sets the username attribute used within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapUserObject = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.user.object",
|
||||
"inetOrgPerson",
|
||||
"Sets the object type of users within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapSearchGroupPrinciple = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.search.group.principle",
|
||||
null,
|
||||
"Sets the principle of the group that users must be a member of",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapGroupObject = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.group.object",
|
||||
"groupOfUniqueNames",
|
||||
"Sets the object type of groups within LDAP",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapGroupUniqueMemberAttribute = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.group.user.uniquemember",
|
||||
"uniquemember",
|
||||
"Sets the attribute for uniquemembers within a group",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private static final ConfigKey<String> ldapTrustStore = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.truststore",
|
||||
null,
|
||||
"Sets the path to the truststore to use for SSL",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
private static final ConfigKey<String> ldapTrustStorePassword = new ConfigKey<String>(
|
||||
"Advanced",
|
||||
String.class,
|
||||
"ldap.truststore.password",
|
||||
null,
|
||||
"Sets the password for the truststore",
|
||||
true,
|
||||
ConfigKey.Scope.Domain);
|
||||
|
||||
private final static int scope = SearchControls.SUBTREE_SCOPE;
|
||||
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
|
||||
@Inject
|
||||
private LdapConfigurationDao _ldapConfigurationDao;
|
||||
|
||||
public LdapConfiguration() {
|
||||
}
|
||||
|
||||
public LdapConfiguration(final ConfigurationDao configDao, final LdapConfigurationDao ldapConfigurationDao) {
|
||||
_configDao = configDao;
|
||||
public LdapConfiguration(final LdapConfigurationDao ldapConfigurationDao) {
|
||||
_ldapConfigurationDao = ldapConfigurationDao;
|
||||
}
|
||||
|
||||
public String getAuthentication() {
|
||||
if ((getBindPrincipal() == null) && (getBindPassword() == null)) {
|
||||
@Deprecated
|
||||
public LdapConfiguration(final ConfigurationDao configDao, final LdapConfigurationDao ldapConfigurationDao) {
|
||||
_ldapConfigurationDao = ldapConfigurationDao;
|
||||
}
|
||||
|
||||
public String getAuthentication(final Long domainId) {
|
||||
if ((getBindPrincipal(domainId) == null) && (getBindPassword(domainId) == null)) {
|
||||
return "none";
|
||||
} else {
|
||||
return "simple";
|
||||
}
|
||||
}
|
||||
|
||||
public String getBaseDn() {
|
||||
return _configDao.getValue("ldap.basedn");
|
||||
public String getBaseDn(final Long domainId) {
|
||||
return ldapBaseDn.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getBindPassword() {
|
||||
return _configDao.getValue("ldap.bind.password");
|
||||
public String getBindPassword(final Long domainId) {
|
||||
return ldapBindPassword.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getBindPrincipal() {
|
||||
return _configDao.getValue("ldap.bind.principal");
|
||||
public String getBindPrincipal(final Long domainId) {
|
||||
return ldapBindPrincipal.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getEmailAttribute() {
|
||||
final String emailAttribute = _configDao.getValue("ldap.email.attribute");
|
||||
return emailAttribute == null ? "mail" : emailAttribute;
|
||||
public String getEmailAttribute(final Long domainId) {
|
||||
return ldapEmailAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public String getFirstnameAttribute() {
|
||||
final String firstnameAttribute = _configDao.getValue("ldap.firstname.attribute");
|
||||
return firstnameAttribute == null ? "givenname" : firstnameAttribute;
|
||||
public String getFirstnameAttribute(final Long domainId) {
|
||||
return ldapFirstnameAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getLastnameAttribute() {
|
||||
final String lastnameAttribute = _configDao.getValue("ldap.lastname.attribute");
|
||||
return lastnameAttribute == null ? "sn" : lastnameAttribute;
|
||||
public String getLastnameAttribute(final Long domainId) {
|
||||
return ldapLastnameAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getProviderUrl() {
|
||||
public String getProviderUrl(final Long domainId) {
|
||||
final String protocol = getSSLStatus() == true ? "ldaps://" : "ldap://";
|
||||
final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(null, 0);
|
||||
final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(null, 0, domainId);
|
||||
final StringBuilder providerUrls = new StringBuilder();
|
||||
String delim = "";
|
||||
for (final LdapConfigurationVO resource : result.first()) {
|
||||
|
|
@ -110,17 +250,24 @@ public class LdapConfiguration implements Configurable{
|
|||
return providerUrls.toString();
|
||||
}
|
||||
|
||||
public String[] getReturnAttributes() {
|
||||
return new String[] {getUsernameAttribute(), getEmailAttribute(), getFirstnameAttribute(), getLastnameAttribute(), getCommonNameAttribute(),
|
||||
getUserAccountControlAttribute()};
|
||||
public String[] getReturnAttributes(final Long domainId) {
|
||||
return new String[] {
|
||||
getUsernameAttribute(domainId),
|
||||
getEmailAttribute(domainId),
|
||||
getFirstnameAttribute(domainId),
|
||||
getLastnameAttribute(domainId),
|
||||
getCommonNameAttribute(),
|
||||
getUserAccountControlAttribute(),
|
||||
getUserMemberOfAttribute(domainId)
|
||||
};
|
||||
}
|
||||
|
||||
public int getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public String getSearchGroupPrinciple() {
|
||||
return _configDao.getValue("ldap.search.group.principle");
|
||||
public String getSearchGroupPrinciple(final Long domainId) {
|
||||
return ldapSearchGroupPrinciple.valueIn(domainId);
|
||||
}
|
||||
|
||||
public boolean getSSLStatus() {
|
||||
|
|
@ -132,53 +279,51 @@ public class LdapConfiguration implements Configurable{
|
|||
}
|
||||
|
||||
public String getTrustStore() {
|
||||
return _configDao.getValue("ldap.truststore");
|
||||
return ldapTrustStore.value();
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return _configDao.getValue("ldap.truststore.password");
|
||||
return ldapTrustStorePassword.value();
|
||||
}
|
||||
|
||||
public String getUsernameAttribute() {
|
||||
final String usernameAttribute = _configDao.getValue("ldap.username.attribute");
|
||||
return usernameAttribute == null ? "uid" : usernameAttribute;
|
||||
public String getUsernameAttribute(final Long domainId) {
|
||||
return ldapUsernameAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getUserObject() {
|
||||
final String userObject = _configDao.getValue("ldap.user.object");
|
||||
return userObject == null ? "inetOrgPerson" : userObject;
|
||||
public String getUserObject(final Long domainId) {
|
||||
return ldapUserObject.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getGroupObject() {
|
||||
final String groupObject = _configDao.getValue("ldap.group.object");
|
||||
return groupObject == null ? "groupOfUniqueNames" : groupObject;
|
||||
public String getGroupObject(final Long domainId) {
|
||||
return ldapGroupObject.valueIn(domainId);
|
||||
}
|
||||
|
||||
public String getGroupUniqueMemeberAttribute() {
|
||||
final String uniqueMemberAttribute = _configDao.getValue("ldap.group.user.uniquemember");
|
||||
return uniqueMemberAttribute == null ? "uniquemember" : uniqueMemberAttribute;
|
||||
public String getGroupUniqueMemberAttribute(final Long domainId) {
|
||||
return ldapGroupUniqueMemberAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
// TODO remove hard-coding
|
||||
public String getCommonNameAttribute() {
|
||||
return "cn";
|
||||
}
|
||||
|
||||
// TODO remove hard-coding
|
||||
public String getUserAccountControlAttribute() {
|
||||
return "userAccountControl";
|
||||
}
|
||||
|
||||
public Long getReadTimeout() {
|
||||
return ldapReadTimeout.value();
|
||||
public Long getReadTimeout(final Long domainId) {
|
||||
return ldapReadTimeout.valueIn(domainId);
|
||||
}
|
||||
|
||||
public Integer getLdapPageSize() {
|
||||
return ldapPageSize.value();
|
||||
public Integer getLdapPageSize(final Long domainId) {
|
||||
return ldapPageSize.valueIn(domainId);
|
||||
}
|
||||
|
||||
public LdapUserManager.Provider getLdapProvider() {
|
||||
public LdapUserManager.Provider getLdapProvider(final Long domainId) {
|
||||
LdapUserManager.Provider provider;
|
||||
try {
|
||||
provider = LdapUserManager.Provider.valueOf(ldapProvider.value().toUpperCase());
|
||||
provider = LdapUserManager.Provider.valueOf(ldapProvider.valueIn(domainId).toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//openldap is the default
|
||||
provider = LdapUserManager.Provider.OPENLDAP;
|
||||
|
|
@ -186,8 +331,12 @@ public class LdapConfiguration implements Configurable{
|
|||
return provider;
|
||||
}
|
||||
|
||||
public boolean isNestedGroupsEnabled() {
|
||||
return ldapEnableNestedGroups.value();
|
||||
public boolean isNestedGroupsEnabled(final Long domainId) {
|
||||
return ldapEnableNestedGroups.valueIn(domainId);
|
||||
}
|
||||
|
||||
public static String getUserMemberOfAttribute(final Long domainId) {
|
||||
return ldapMemberOfAttribute.valueIn(domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -197,6 +346,25 @@ public class LdapConfiguration implements Configurable{
|
|||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {ldapReadTimeout, ldapPageSize, ldapProvider, ldapEnableNestedGroups};
|
||||
return new ConfigKey<?>[]{
|
||||
ldapReadTimeout,
|
||||
ldapPageSize,
|
||||
ldapProvider,
|
||||
ldapEnableNestedGroups,
|
||||
ldapBaseDn,
|
||||
ldapBindPassword,
|
||||
ldapBindPrincipal,
|
||||
ldapEmailAttribute,
|
||||
ldapFirstnameAttribute,
|
||||
ldapLastnameAttribute,
|
||||
ldapUsernameAttribute,
|
||||
ldapUserObject,
|
||||
ldapSearchGroupPrinciple,
|
||||
ldapGroupObject,
|
||||
ldapGroupUniqueMemberAttribute,
|
||||
ldapTrustStore,
|
||||
ldapTrustStorePassword,
|
||||
ldapMemberOfAttribute
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,12 +39,16 @@ public class LdapConfigurationVO implements InternalIdentity {
|
|||
@Column(name = "port")
|
||||
private int port;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private Long domainId;
|
||||
|
||||
public LdapConfigurationVO() {
|
||||
}
|
||||
|
||||
public LdapConfigurationVO(final String hostname, final int port) {
|
||||
public LdapConfigurationVO(final String hostname, final int port, final Long domainId) {
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
|
|
@ -60,6 +64,10 @@ public class LdapConfigurationVO implements InternalIdentity {
|
|||
return port;
|
||||
}
|
||||
|
||||
public Long getDomainId() {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,29 +40,31 @@ public class LdapContextFactory {
|
|||
_ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
|
||||
public LdapContext createBindContext() throws NamingException, IOException {
|
||||
return createBindContext(null);
|
||||
// TODO add optional domain (optional only for backwards compatibility)
|
||||
public LdapContext createBindContext(Long domainId) throws NamingException, IOException {
|
||||
return createBindContext(null, domainId);
|
||||
}
|
||||
|
||||
public LdapContext createBindContext(final String providerUrl) throws NamingException, IOException {
|
||||
final String bindPrincipal = _ldapConfiguration.getBindPrincipal();
|
||||
final String bindPassword = _ldapConfiguration.getBindPassword();
|
||||
return createInitialDirContext(bindPrincipal, bindPassword, providerUrl, true);
|
||||
// TODO add optional domain (optional only for backwards compatibility)
|
||||
public LdapContext createBindContext(final String providerUrl, Long domainId) throws NamingException, IOException {
|
||||
final String bindPrincipal = _ldapConfiguration.getBindPrincipal(domainId);
|
||||
final String bindPassword = _ldapConfiguration.getBindPassword(domainId);
|
||||
return createInitialDirContext(bindPrincipal, bindPassword, providerUrl, true, domainId);
|
||||
}
|
||||
|
||||
private LdapContext createInitialDirContext(final String principal, final String password, final boolean isSystemContext) throws NamingException, IOException {
|
||||
return createInitialDirContext(principal, password, null, isSystemContext);
|
||||
private LdapContext createInitialDirContext(final String principal, final String password, final boolean isSystemContext, Long domainId) throws NamingException, IOException {
|
||||
return createInitialDirContext(principal, password, null, isSystemContext, domainId);
|
||||
}
|
||||
|
||||
private LdapContext createInitialDirContext(final String principal, final String password, final String providerUrl, final boolean isSystemContext)
|
||||
private LdapContext createInitialDirContext(final String principal, final String password, final String providerUrl, final boolean isSystemContext, Long domainId)
|
||||
throws NamingException, IOException {
|
||||
Hashtable<String, String> environment = getEnvironment(principal, password, providerUrl, isSystemContext);
|
||||
Hashtable<String, String> environment = getEnvironment(principal, password, providerUrl, isSystemContext, domainId);
|
||||
s_logger.debug("initializing ldap with provider url: " + environment.get(Context.PROVIDER_URL));
|
||||
return new InitialLdapContext(environment, null);
|
||||
}
|
||||
|
||||
public LdapContext createUserContext(final String principal, final String password) throws NamingException, IOException {
|
||||
return createInitialDirContext(principal, password, false);
|
||||
public LdapContext createUserContext(final String principal, final String password, Long domainId) throws NamingException, IOException {
|
||||
return createInitialDirContext(principal, password, false, domainId);
|
||||
}
|
||||
|
||||
private void enableSSL(final Hashtable<String, String> environment) {
|
||||
|
|
@ -76,19 +78,19 @@ public class LdapContextFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private Hashtable<String, String> getEnvironment(final String principal, final String password, final String providerUrl, final boolean isSystemContext) {
|
||||
private Hashtable<String, String> getEnvironment(final String principal, final String password, final String providerUrl, final boolean isSystemContext, Long domainId) {
|
||||
final String factory = _ldapConfiguration.getFactory();
|
||||
final String url = providerUrl == null ? _ldapConfiguration.getProviderUrl() : providerUrl;
|
||||
final String url = providerUrl == null ? _ldapConfiguration.getProviderUrl(domainId) : providerUrl;
|
||||
|
||||
final Hashtable<String, String> environment = new Hashtable<String, String>();
|
||||
|
||||
environment.put(Context.INITIAL_CONTEXT_FACTORY, factory);
|
||||
environment.put(Context.PROVIDER_URL, url);
|
||||
environment.put("com.sun.jndi.ldap.read.timeout", _ldapConfiguration.getReadTimeout().toString());
|
||||
environment.put("com.sun.jndi.ldap.read.timeout", _ldapConfiguration.getReadTimeout(domainId).toString());
|
||||
environment.put("com.sun.jndi.ldap.connect.pool", "true");
|
||||
|
||||
enableSSL(environment);
|
||||
setAuthentication(environment, isSystemContext);
|
||||
setAuthentication(environment, isSystemContext, domainId);
|
||||
|
||||
if (principal != null) {
|
||||
environment.put(Context.SECURITY_PRINCIPAL, principal);
|
||||
|
|
@ -101,8 +103,8 @@ public class LdapContextFactory {
|
|||
return environment;
|
||||
}
|
||||
|
||||
private void setAuthentication(final Hashtable<String, String> environment, final boolean isSystemContext) {
|
||||
final String authentication = _ldapConfiguration.getAuthentication();
|
||||
private void setAuthentication(final Hashtable<String, String> environment, final boolean isSystemContext, final Long domainId) {
|
||||
final String authentication = _ldapConfiguration.getAuthentication(domainId);
|
||||
|
||||
if ("none".equals(authentication) && !isSystemContext) {
|
||||
environment.put(Context.SECURITY_AUTHENTICATION, "simple");
|
||||
|
|
|
|||
|
|
@ -18,36 +18,48 @@ package org.apache.cloudstack.ldap;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.LdapAddConfigurationCmd;
|
||||
import org.apache.cloudstack.api.command.LdapDeleteConfigurationCmd;
|
||||
import org.apache.cloudstack.api.command.LdapListConfigurationCmd;
|
||||
import org.apache.cloudstack.api.command.LinkAccountToLdapCmd;
|
||||
import org.apache.cloudstack.api.command.LinkDomainToLdapCmd;
|
||||
import org.apache.cloudstack.api.response.LdapConfigurationResponse;
|
||||
import org.apache.cloudstack.api.response.LdapUserResponse;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import org.apache.cloudstack.api.response.LinkAccountToLdapResponse;
|
||||
import org.apache.cloudstack.api.response.LinkDomainToLdapResponse;
|
||||
|
||||
public interface LdapManager extends PluggableService {
|
||||
|
||||
enum LinkType { GROUP, OU;}
|
||||
|
||||
LdapConfigurationResponse addConfiguration(String hostname, int port) throws InvalidParameterValueException;
|
||||
LdapConfigurationResponse addConfiguration(final LdapAddConfigurationCmd cmd) throws InvalidParameterValueException;
|
||||
|
||||
boolean canAuthenticate(String principal, String password);
|
||||
@Deprecated
|
||||
LdapConfigurationResponse addConfiguration(String hostname, int port, Long domainId) throws InvalidParameterValueException;
|
||||
|
||||
boolean canAuthenticate(String principal, String password, final Long domainId);
|
||||
|
||||
LdapConfigurationResponse createLdapConfigurationResponse(LdapConfigurationVO configuration);
|
||||
|
||||
LdapUserResponse createLdapUserResponse(LdapUser user);
|
||||
|
||||
LdapConfigurationResponse deleteConfiguration(String hostname) throws InvalidParameterValueException;
|
||||
LdapConfigurationResponse deleteConfiguration(LdapDeleteConfigurationCmd cmd) throws InvalidParameterValueException;
|
||||
|
||||
LdapUser getUser(final String username) throws NoLdapUserMatchingQueryException;
|
||||
@Deprecated
|
||||
LdapConfigurationResponse deleteConfiguration(String hostname, int port, Long domainId) throws InvalidParameterValueException;
|
||||
|
||||
LdapUser getUser(String username, String type, String name) throws NoLdapUserMatchingQueryException;
|
||||
// TODO username is only unique withing domain scope (add domain id to call)
|
||||
LdapUser getUser(final String username, Long domainId) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
List<LdapUser> getUsers() throws NoLdapUserMatchingQueryException;
|
||||
LdapUser getUser(String username, String type, String name, Long domainId) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
List<LdapUser> getUsersInGroup(String groupName) throws NoLdapUserMatchingQueryException;
|
||||
List<LdapUser> getUsers(Long domainId) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
List<LdapUser> getUsersInGroup(String groupName, Long domainId) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
boolean isLdapEnabled();
|
||||
|
||||
|
|
@ -55,7 +67,15 @@ public interface LdapManager extends PluggableService {
|
|||
|
||||
List<LdapUser> searchUsers(String query) throws NoLdapUserMatchingQueryException;
|
||||
|
||||
LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name, short accountType);
|
||||
LinkDomainToLdapResponse linkDomainToLdap(LinkDomainToLdapCmd cmd);
|
||||
|
||||
public LdapTrustMapVO getDomainLinkedToLdap(long domainId);
|
||||
LdapTrustMapVO getDomainLinkedToLdap(long domainId);
|
||||
|
||||
List<LdapTrustMapVO> getDomainLinkage(long domainId);
|
||||
|
||||
LdapTrustMapVO getAccountLinkedToLdap(long domainId, long accountId);
|
||||
|
||||
LdapTrustMapVO getLinkedLdapGroup(long domainId, String group);
|
||||
|
||||
LinkAccountToLdapResponse linkAccountToLdap(LinkAccountToLdapCmd linkAccountToLdapCmd);
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.api.LdapValidator;
|
||||
import org.apache.cloudstack.api.command.LDAPConfigCmd;
|
||||
|
|
@ -34,9 +35,11 @@ import org.apache.cloudstack.api.command.LdapImportUsersCmd;
|
|||
import org.apache.cloudstack.api.command.LdapListConfigurationCmd;
|
||||
import org.apache.cloudstack.api.command.LdapListUsersCmd;
|
||||
import org.apache.cloudstack.api.command.LdapUserSearchCmd;
|
||||
import org.apache.cloudstack.api.command.LinkAccountToLdapCmd;
|
||||
import org.apache.cloudstack.api.command.LinkDomainToLdapCmd;
|
||||
import org.apache.cloudstack.api.response.LdapConfigurationResponse;
|
||||
import org.apache.cloudstack.api.response.LdapUserResponse;
|
||||
import org.apache.cloudstack.api.response.LinkAccountToLdapResponse;
|
||||
import org.apache.cloudstack.api.response.LinkDomainToLdapResponse;
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDao;
|
||||
import org.apache.cloudstack.ldap.dao.LdapTrustMapDao;
|
||||
|
|
@ -47,6 +50,9 @@ import org.springframework.stereotype.Component;
|
|||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
@Component
|
||||
|
|
@ -59,6 +65,9 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
@Inject
|
||||
private DomainDao domainDao;
|
||||
|
||||
@Inject
|
||||
private AccountDao accountDao;
|
||||
|
||||
@Inject
|
||||
private LdapContextFactory _ldapContextFactory;
|
||||
|
||||
|
|
@ -85,17 +94,32 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LdapConfigurationResponse addConfiguration(final String hostname, final int port) throws InvalidParameterValueException {
|
||||
LdapConfigurationVO configuration = _ldapConfigurationDao.findByHostname(hostname);
|
||||
public LdapConfigurationResponse addConfiguration(final LdapAddConfigurationCmd cmd) throws InvalidParameterValueException {
|
||||
return addConfigurationInternal(cmd.getHostname(),cmd.getPort(),cmd.getDomainId());
|
||||
}
|
||||
|
||||
@Override // TODO make private
|
||||
public LdapConfigurationResponse addConfiguration(final String hostname, int port, final Long domainId) throws InvalidParameterValueException {
|
||||
return addConfigurationInternal(hostname,port,domainId);
|
||||
}
|
||||
|
||||
private LdapConfigurationResponse addConfigurationInternal(final String hostname, int port, final Long domainId) throws InvalidParameterValueException {
|
||||
// TODO evaluate what the right default should be
|
||||
if(port <= 0) {
|
||||
port = 389;
|
||||
}
|
||||
|
||||
// hostname:port is unique for domain binding
|
||||
LdapConfigurationVO configuration = _ldapConfigurationDao.find(hostname, port, domainId);
|
||||
if (configuration == null) {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
final String providerUrl = "ldap://" + hostname + ":" + port;
|
||||
context = _ldapContextFactory.createBindContext(providerUrl);
|
||||
configuration = new LdapConfigurationVO(hostname, port);
|
||||
context = _ldapContextFactory.createBindContext(providerUrl,domainId);
|
||||
configuration = new LdapConfigurationVO(hostname, port, domainId);
|
||||
_ldapConfigurationDao.persist(configuration);
|
||||
s_logger.info("Added new ldap server with hostname: " + hostname);
|
||||
return new LdapConfigurationResponse(hostname, port);
|
||||
s_logger.info("Added new ldap server with url: " + providerUrl + (domainId == null ? "": " for domain " + domainId));
|
||||
return createLdapConfigurationResponse(configuration);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("NamingException while doing an LDAP bind", e);
|
||||
throw new InvalidParameterValueException("Unable to bind to the given LDAP server");
|
||||
|
|
@ -107,10 +131,18 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO decide if the principal is good enough to get the domain id or we need to add it as parameter
|
||||
* @param principal
|
||||
* @param password
|
||||
* @param domainId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean canAuthenticate(final String principal, final String password) {
|
||||
public boolean canAuthenticate(final String principal, final String password, final Long domainId) {
|
||||
try {
|
||||
final LdapContext context = _ldapContextFactory.createUserContext(principal, password);
|
||||
// TODO return the right account for this user
|
||||
final LdapContext context = _ldapContextFactory.createUserContext(principal, password,domainId);
|
||||
closeContext(context);
|
||||
return true;
|
||||
} catch (NamingException | IOException e) {
|
||||
|
|
@ -132,10 +164,11 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
|
||||
@Override
|
||||
public LdapConfigurationResponse createLdapConfigurationResponse(final LdapConfigurationVO configuration) {
|
||||
final LdapConfigurationResponse response = new LdapConfigurationResponse();
|
||||
response.setHostname(configuration.getHostname());
|
||||
response.setPort(configuration.getPort());
|
||||
return response;
|
||||
String domainUuid = null;
|
||||
if(configuration.getDomainId() != null) {
|
||||
domainUuid = domainDao.findById(configuration.getDomainId()).getUuid();
|
||||
}
|
||||
return new LdapConfigurationResponse(configuration.getHostname(), configuration.getPort(), domainUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -151,14 +184,23 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LdapConfigurationResponse deleteConfiguration(final String hostname) throws InvalidParameterValueException {
|
||||
final LdapConfigurationVO configuration = _ldapConfigurationDao.findByHostname(hostname);
|
||||
public LdapConfigurationResponse deleteConfiguration(final LdapDeleteConfigurationCmd cmd) throws InvalidParameterValueException {
|
||||
return deleteConfigurationInternal(cmd.getHostname(), cmd.getPort(), cmd.getDomainId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapConfigurationResponse deleteConfiguration(final String hostname, int port, Long domainId) throws InvalidParameterValueException {
|
||||
return deleteConfigurationInternal(hostname, port, domainId);
|
||||
}
|
||||
|
||||
private LdapConfigurationResponse deleteConfigurationInternal(final String hostname, int port, Long domainId) throws InvalidParameterValueException {
|
||||
final LdapConfigurationVO configuration = _ldapConfigurationDao.find(hostname,port,domainId);
|
||||
if (configuration == null) {
|
||||
throw new InvalidParameterValueException("Cannot find configuration with hostname " + hostname);
|
||||
} else {
|
||||
_ldapConfigurationDao.remove(configuration.getId());
|
||||
s_logger.info("Removed ldap server with hostname: " + hostname);
|
||||
return new LdapConfigurationResponse(configuration.getHostname(), configuration.getPort());
|
||||
s_logger.info("Removed ldap server with url: " + hostname + ':' + port + (domainId == null ? "" : " for domain id " + domainId));
|
||||
return createLdapConfigurationResponse(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,17 +217,18 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
cmdList.add(LDAPConfigCmd.class);
|
||||
cmdList.add(LDAPRemoveCmd.class);
|
||||
cmdList.add(LinkDomainToLdapCmd.class);
|
||||
cmdList.add(LinkAccountToLdapCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapUser getUser(final String username) throws NoLdapUserMatchingQueryException {
|
||||
public LdapUser getUser(final String username, Long domainId) throws NoLdapUserMatchingQueryException {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
context = _ldapContextFactory.createBindContext(domainId);
|
||||
|
||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUser(escapedUsername, context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, context, domainId);
|
||||
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
|
|
@ -196,26 +239,26 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LdapUser getUser(final String username, final String type, final String name) throws NoLdapUserMatchingQueryException {
|
||||
public LdapUser getUser(final String username, final String type, final String name, Long domainId) throws NoLdapUserMatchingQueryException {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
context = _ldapContextFactory.createBindContext(domainId);
|
||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUser(escapedUsername, type, name, context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUser(escapedUsername, type, name, context, domainId);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username + "name: " + name + "of type: " + type);
|
||||
throw new NoLdapUserMatchingQueryException("No Ldap User found for username: "+username + " in group: " + name + " of type: " + type);
|
||||
} finally {
|
||||
closeContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsers() throws NoLdapUserMatchingQueryException {
|
||||
public List<LdapUser> getUsers(Long domainId) throws NoLdapUserMatchingQueryException {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers(context);
|
||||
context = _ldapContextFactory.createBindContext(domainId);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsers(context, domainId);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
throw new NoLdapUserMatchingQueryException("*");
|
||||
|
|
@ -225,11 +268,11 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName) throws NoLdapUserMatchingQueryException {
|
||||
public List<LdapUser> getUsersInGroup(String groupName, Long domainId) throws NoLdapUserMatchingQueryException {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsersInGroup(groupName, context);
|
||||
context = _ldapContextFactory.createBindContext(domainId);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(domainId)).getUsersInGroup(groupName, context, domainId);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap NamingException: ",e);
|
||||
throw new NoLdapUserMatchingQueryException("groupName=" + groupName);
|
||||
|
|
@ -247,7 +290,8 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
public Pair<List<? extends LdapConfigurationVO>, Integer> listConfigurations(final LdapListConfigurationCmd cmd) {
|
||||
final String hostname = cmd.getHostname();
|
||||
final int port = cmd.getPort();
|
||||
final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(hostname, port);
|
||||
final Long domainId = cmd.getDomainId();
|
||||
final Pair<List<LdapConfigurationVO>, Integer> result = _ldapConfigurationDao.searchConfigurations(hostname, port, domainId);
|
||||
return new Pair<List<? extends LdapConfigurationVO>, Integer>(result.first(), result.second());
|
||||
}
|
||||
|
||||
|
|
@ -255,9 +299,10 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
public List<LdapUser> searchUsers(final String username) throws NoLdapUserMatchingQueryException {
|
||||
LdapContext context = null;
|
||||
try {
|
||||
context = _ldapContextFactory.createBindContext();
|
||||
// TODO search users per domain (only?)
|
||||
context = _ldapContextFactory.createBindContext(null);
|
||||
final String escapedUsername = LdapUtils.escapeLDAPSearchFilter(username);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider()).getUsers("*" + escapedUsername + "*", context);
|
||||
return _ldapUserManagerFactory.getInstance(_ldapConfiguration.getLdapProvider(null)).getUsers("*" + escapedUsername + "*", context, null);
|
||||
} catch (NamingException | IOException e) {
|
||||
s_logger.debug("ldap Exception: ",e);
|
||||
throw new NoLdapUserMatchingQueryException(username);
|
||||
|
|
@ -267,14 +312,20 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name, short accountType) {
|
||||
public LinkDomainToLdapResponse linkDomainToLdap(LinkDomainToLdapCmd cmd) {
|
||||
Validate.isTrue(_ldapConfiguration.getBaseDn(cmd.getDomainId()) == null, "can not configure an ldap server and an ldap group/ou to a domain");
|
||||
Validate.notEmpty(cmd.getLdapDomain(), "ldapDomain cannot be empty, please supply a GROUP or OU name");
|
||||
return linkDomainToLdap(cmd.getDomainId(),cmd.getType(),cmd.getLdapDomain(),cmd.getAccountType());
|
||||
}
|
||||
|
||||
private LinkDomainToLdapResponse linkDomainToLdap(Long domainId, String type, String name, short accountType) {
|
||||
Validate.notNull(type, "type cannot be null. It should either be GROUP or OU");
|
||||
Validate.notNull(domainId, "domainId cannot be null.");
|
||||
Validate.notEmpty(name, "GROUP or OU name cannot be empty");
|
||||
//Account type should be 0 or 2. check the constants in com.cloud.user.Account
|
||||
Validate.isTrue(accountType==0 || accountType==2, "accountype should be either 0(normal user) or 2(domain admin)");
|
||||
LinkType linkType = LdapManager.LinkType.valueOf(type.toUpperCase());
|
||||
LdapTrustMapVO vo = _ldapTrustMapDao.persist(new LdapTrustMapVO(domainId, linkType, name, accountType));
|
||||
LdapTrustMapVO vo = _ldapTrustMapDao.persist(new LdapTrustMapVO(domainId, linkType, name, accountType, 0));
|
||||
DomainVO domain = domainDao.findById(vo.getDomainId());
|
||||
String domainUuid = "<unknown>";
|
||||
if (domain == null) {
|
||||
|
|
@ -290,4 +341,46 @@ public class LdapManagerImpl implements LdapManager, LdapValidator {
|
|||
public LdapTrustMapVO getDomainLinkedToLdap(long domainId){
|
||||
return _ldapTrustMapDao.findByDomainId(domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapTrustMapVO> getDomainLinkage(long domainId){
|
||||
return _ldapTrustMapDao.searchByDomainId(domainId);
|
||||
}
|
||||
|
||||
public LdapTrustMapVO getAccountLinkedToLdap(long domainId, long accountId){
|
||||
return _ldapTrustMapDao.findByAccount(domainId, accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapTrustMapVO getLinkedLdapGroup(long domainId, String group) {
|
||||
return _ldapTrustMapDao.findGroupInDomain(domainId, group);
|
||||
}
|
||||
|
||||
@Override public LinkAccountToLdapResponse linkAccountToLdap(LinkAccountToLdapCmd cmd) {
|
||||
Validate.notNull(_ldapConfiguration.getBaseDn(cmd.getDomainId()), "can not configure an ldap server and an ldap group/ou to a domain");
|
||||
Validate.notNull(cmd.getDomainId(), "domainId cannot be null.");
|
||||
Validate.notEmpty(cmd.getAccountName(), "accountName cannot be empty.");
|
||||
Validate.notEmpty(cmd.getLdapDomain(), "ldapDomain cannot be empty, please supply a GROUP or OU name");
|
||||
Validate.notNull(cmd.getType(), "type cannot be null. It should either be GROUP or OU");
|
||||
Validate.notEmpty(cmd.getLdapDomain(), "GROUP or OU name cannot be empty");
|
||||
|
||||
LinkType linkType = LdapManager.LinkType.valueOf(cmd.getType().toUpperCase());
|
||||
Account account = accountDao.findActiveAccount(cmd.getAccountName(),cmd.getDomainId());
|
||||
if (account == null) {
|
||||
account = new AccountVO(cmd.getAccountName(), cmd.getDomainId(), null, cmd.getAccountType(), UUID.randomUUID().toString());
|
||||
accountDao.persist((AccountVO)account);
|
||||
}
|
||||
Long accountId = account.getAccountId();
|
||||
LdapTrustMapVO vo = _ldapTrustMapDao.persist(new LdapTrustMapVO(cmd.getDomainId(), linkType, cmd.getLdapDomain(), cmd.getAccountType(), accountId));
|
||||
DomainVO domain = domainDao.findById(vo.getDomainId());
|
||||
String domainUuid = "<unknown>";
|
||||
if (domain == null) {
|
||||
s_logger.error("no domain in database for id " + vo.getDomainId());
|
||||
} else {
|
||||
domainUuid = domain.getUuid();
|
||||
}
|
||||
|
||||
LinkAccountToLdapResponse response = new LinkAccountToLdapResponse(domainUuid, vo.getType().toString(), vo.getName(), vo.getAccountType(), account.getUuid(), cmd.getAccountName());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ public class LdapTrustMapVO implements InternalIdentity {
|
|||
@Column(name = "domain_id")
|
||||
private long domainId;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private long accountId;
|
||||
|
||||
@Column(name = "account_type")
|
||||
private short accountType;
|
||||
|
||||
|
|
@ -52,11 +55,12 @@ public class LdapTrustMapVO implements InternalIdentity {
|
|||
public LdapTrustMapVO() {
|
||||
}
|
||||
|
||||
public LdapTrustMapVO(long domainId, LdapManager.LinkType type, String name, short accountType) {
|
||||
public LdapTrustMapVO(long domainId, LdapManager.LinkType type, String name, short accountType, long accountId) {
|
||||
this.domainId = domainId;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.accountType = accountType;
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,6 +84,10 @@ public class LdapTrustMapVO implements InternalIdentity {
|
|||
return accountType;
|
||||
}
|
||||
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
|
|
@ -94,6 +102,9 @@ public class LdapTrustMapVO implements InternalIdentity {
|
|||
if (domainId != that.domainId) {
|
||||
return false;
|
||||
}
|
||||
if (accountId != that.accountId) {
|
||||
return false;
|
||||
}
|
||||
if (accountType != that.accountType) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -109,6 +120,7 @@ public class LdapTrustMapVO implements InternalIdentity {
|
|||
int result = type.hashCode();
|
||||
result = 31 * result + name.hashCode();
|
||||
result = 31 * result + (int) (domainId ^ (domainId >>> 32));
|
||||
result = 31 * result + (int) (accountId ^ (accountId >>> 32));
|
||||
result = 31 * result + (int) accountType;
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class LdapUser implements Comparable<LdapUser> {
|
||||
private final String email;
|
||||
private final String principal;
|
||||
|
|
@ -24,8 +27,10 @@ public class LdapUser implements Comparable<LdapUser> {
|
|||
private final String username;
|
||||
private final String domain;
|
||||
private final boolean disabled;
|
||||
private List<String> memberships;
|
||||
|
||||
public LdapUser(final String username, final String email, final String firstname, final String lastname, final String principal, String domain, boolean disabled) {
|
||||
public LdapUser(final String username, final String email, final String firstname, final String lastname, final String principal, String domain, boolean disabled,
|
||||
List<String> memberships) {
|
||||
this.username = username;
|
||||
this.email = email;
|
||||
this.firstname = firstname;
|
||||
|
|
@ -33,6 +38,7 @@ public class LdapUser implements Comparable<LdapUser> {
|
|||
this.principal = principal;
|
||||
this.domain = domain;
|
||||
this.disabled = disabled;
|
||||
this.memberships = memberships == null ? new ArrayList<>() : memberships;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,6 +86,9 @@ public class LdapUser implements Comparable<LdapUser> {
|
|||
return disabled;
|
||||
}
|
||||
|
||||
public List<String> getMemberships() {
|
||||
return memberships;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
|
|
|||
|
|
@ -30,17 +30,17 @@ public interface LdapUserManager {
|
|||
MICROSOFTAD, OPENLDAP;
|
||||
}
|
||||
|
||||
public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
public LdapUser getUser(final String username, final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
|
||||
public LdapUser getUser(final String username, final String type, final String name, final LdapContext context) throws NamingException, IOException;
|
||||
public LdapUser getUser(final String username, final String type, final String name, final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
|
||||
public List<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException;
|
||||
public List<LdapUser> getUsers(final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException;
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context, Long domainId) throws NamingException;
|
||||
|
||||
public List<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException;
|
||||
public List<LdapUser> searchUsers(final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException;
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context, Long domainId) throws NamingException, IOException;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,12 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.ldap;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class LdapUtils {
|
||||
public static String escapeLDAPSearchFilter(final String filter) {
|
||||
|
|
@ -56,6 +59,18 @@ public final class LdapUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static List<String> getAttributeValues(final Attributes attributes, final String attributeName) throws NamingException {
|
||||
ArrayList<String> memberships = new ArrayList<>();
|
||||
final Attribute attribute = attributes.get(attributeName);
|
||||
if (attribute != null) {
|
||||
NamingEnumeration<?> values = attribute.getAll();
|
||||
while(values.hasMore()) {
|
||||
memberships.add(String.valueOf(values.next()));
|
||||
}
|
||||
}
|
||||
return memberships;
|
||||
}
|
||||
|
||||
private LdapUtils() {
|
||||
}
|
||||
}
|
||||
|
|
@ -50,41 +50,46 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
_ldapConfiguration = ldapConfiguration;
|
||||
}
|
||||
|
||||
protected LdapUser createUser(final SearchResult result) throws NamingException {
|
||||
protected LdapUser createUser(final SearchResult result, Long domainId) throws NamingException {
|
||||
final Attributes attributes = result.getAttributes();
|
||||
|
||||
final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute());
|
||||
final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute());
|
||||
final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute());
|
||||
final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute());
|
||||
final String username = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getUsernameAttribute(domainId));
|
||||
final String email = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getEmailAttribute(domainId));
|
||||
final String firstname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getFirstnameAttribute(domainId));
|
||||
final String lastname = LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getLastnameAttribute(domainId));
|
||||
final String principal = result.getNameInNamespace();
|
||||
final List<String> memberships = LdapUtils.getAttributeValues(attributes, _ldapConfiguration.getUserMemberOfAttribute(domainId));
|
||||
|
||||
String domain = principal.replace("cn=" + LdapUtils.getAttributeValue(attributes, _ldapConfiguration.getCommonNameAttribute()) + ",", "");
|
||||
domain = domain.replace("," + _ldapConfiguration.getBaseDn(), "");
|
||||
domain = domain.replace("," + _ldapConfiguration.getBaseDn(domainId), "");
|
||||
domain = domain.replace("ou=", "");
|
||||
|
||||
boolean disabled = isUserDisabled(result);
|
||||
|
||||
return new LdapUser(username, email, firstname, lastname, principal, domain, disabled);
|
||||
return new LdapUser(username, email, firstname, lastname, principal, domain, disabled, memberships);
|
||||
}
|
||||
|
||||
private String generateSearchFilter(final String username) {
|
||||
private String generateSearchFilter(final String username, Long domainId) {
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject(domainId));
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder usernameFilter = new StringBuilder();
|
||||
usernameFilter.append("(");
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute(domainId));
|
||||
usernameFilter.append("=");
|
||||
usernameFilter.append((username == null ? "*" : username));
|
||||
usernameFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
if (_ldapConfiguration.getSearchGroupPrinciple() != null) {
|
||||
memberOfFilter.append("(memberof=");
|
||||
memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple());
|
||||
if (_ldapConfiguration.getSearchGroupPrinciple(domainId) != null) {
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("adding search filter for '" + _ldapConfiguration.getSearchGroupPrinciple(domainId) +
|
||||
"', using " + _ldapConfiguration.getUserMemberOfAttribute(domainId));
|
||||
}
|
||||
memberOfFilter.append("(" + _ldapConfiguration.getUserMemberOfAttribute(domainId) + "=");
|
||||
memberOfFilter.append(_ldapConfiguration.getSearchGroupPrinciple(domainId));
|
||||
memberOfFilter.append(")");
|
||||
}
|
||||
|
||||
|
|
@ -98,10 +103,10 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
private String generateGroupSearchFilter(final String groupName) {
|
||||
private String generateGroupSearchFilter(final String groupName, Long domainId) {
|
||||
final StringBuilder groupObjectFilter = new StringBuilder();
|
||||
groupObjectFilter.append("(objectClass=");
|
||||
groupObjectFilter.append(_ldapConfiguration.getGroupObject());
|
||||
groupObjectFilter.append(_ldapConfiguration.getGroupObject(domainId));
|
||||
groupObjectFilter.append(")");
|
||||
|
||||
final StringBuilder groupNameFilter = new StringBuilder();
|
||||
|
|
@ -121,8 +126,8 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LdapUser getUser(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> result = searchUsers(username, context);
|
||||
public LdapUser getUser(final String username, final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
List<LdapUser> result = searchUsers(username, context, domainId);
|
||||
if (result!= null && result.size() == 1) {
|
||||
return result.get(0);
|
||||
} else {
|
||||
|
|
@ -131,29 +136,29 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public LdapUser getUser(final String username, final String type, final String name, final LdapContext context) throws NamingException, IOException {
|
||||
public LdapUser getUser(final String username, final String type, final String name, final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
String basedn;
|
||||
if("OU".equals(type)) {
|
||||
basedn = name;
|
||||
} else {
|
||||
basedn = _ldapConfiguration.getBaseDn();
|
||||
basedn = _ldapConfiguration.getBaseDn(domainId);
|
||||
}
|
||||
|
||||
final StringBuilder userObjectFilter = new StringBuilder();
|
||||
userObjectFilter.append("(objectClass=");
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject());
|
||||
userObjectFilter.append(_ldapConfiguration.getUserObject(domainId));
|
||||
userObjectFilter.append(")");
|
||||
|
||||
final StringBuilder usernameFilter = new StringBuilder();
|
||||
usernameFilter.append("(");
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute());
|
||||
usernameFilter.append(_ldapConfiguration.getUsernameAttribute(domainId));
|
||||
usernameFilter.append("=");
|
||||
usernameFilter.append((username == null ? "*" : username));
|
||||
usernameFilter.append(")");
|
||||
|
||||
final StringBuilder memberOfFilter = new StringBuilder();
|
||||
if ("GROUP".equals(type)) {
|
||||
memberOfFilter.append("(").append(getMemberOfAttribute()).append("=");
|
||||
memberOfFilter.append("(").append(getMemberOfAttribute(domainId)).append("=");
|
||||
memberOfFilter.append(name);
|
||||
memberOfFilter.append(")");
|
||||
}
|
||||
|
|
@ -165,21 +170,21 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
searchQuery.append(memberOfFilter);
|
||||
searchQuery.append(")");
|
||||
|
||||
return searchUser(basedn, searchQuery.toString(), context);
|
||||
return searchUser(basedn, searchQuery.toString(), context, domainId);
|
||||
}
|
||||
|
||||
protected String getMemberOfAttribute() {
|
||||
return "memberof";
|
||||
protected String getMemberOfAttribute(final Long domainId) {
|
||||
return _ldapConfiguration.getUserMemberOfAttribute(domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return getUsers(null, context);
|
||||
public List<LdapUser> getUsers(final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
return getUsers(null, context, domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
List<LdapUser> users = searchUsers(username, context);
|
||||
public List<LdapUser> getUsers(final String username, final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
List<LdapUser> users = searchUsers(username, context, domainId);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(users)) {
|
||||
Collections.sort(users);
|
||||
|
|
@ -188,13 +193,13 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context) throws NamingException {
|
||||
String attributeName = _ldapConfiguration.getGroupUniqueMemeberAttribute();
|
||||
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context, Long domainId) throws NamingException {
|
||||
String attributeName = _ldapConfiguration.getGroupUniqueMemberAttribute(domainId);
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(new String[] {attributeName});
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(), generateGroupSearchFilter(groupName), controls);
|
||||
NamingEnumeration<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(domainId), generateGroupSearchFilter(groupName, domainId), controls);
|
||||
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
//Expecting only one result which has all the users
|
||||
|
|
@ -205,7 +210,7 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
while (values.hasMoreElements()) {
|
||||
String userdn = String.valueOf(values.nextElement());
|
||||
try{
|
||||
users.add(getUserForDn(userdn, context));
|
||||
users.add(getUserForDn(userdn, context, domainId));
|
||||
} catch (NamingException e){
|
||||
s_logger.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
|
||||
}
|
||||
|
|
@ -217,39 +222,42 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
return users;
|
||||
}
|
||||
|
||||
private LdapUser getUserForDn(String userdn, LdapContext context) throws NamingException {
|
||||
private LdapUser getUserForDn(String userdn, LdapContext context, Long domainId) throws NamingException {
|
||||
final SearchControls controls = new SearchControls();
|
||||
controls.setSearchScope(_ldapConfiguration.getScope());
|
||||
controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes(domainId));
|
||||
|
||||
NamingEnumeration<SearchResult> result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
|
||||
NamingEnumeration<SearchResult> result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject(domainId) + ")", controls);
|
||||
if (result.hasMoreElements()) {
|
||||
return createUser(result.nextElement());
|
||||
return createUser(result.nextElement(), domainId);
|
||||
} else {
|
||||
throw new NamingException("No user found for dn " + userdn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> searchUsers(final LdapContext context) throws NamingException, IOException {
|
||||
return searchUsers(null, context);
|
||||
public List<LdapUser> searchUsers(final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
return searchUsers(null, context, domainId);
|
||||
}
|
||||
|
||||
protected boolean isUserDisabled(SearchResult result) throws NamingException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public LdapUser searchUser(final String basedn, final String searchString, final LdapContext context) throws NamingException, IOException {
|
||||
public LdapUser searchUser(final String basedn, final String searchString, final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes(domainId));
|
||||
|
||||
NamingEnumeration<SearchResult> results = context.search(basedn, searchString, searchControls);
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("searching user(s) with filter: \"" + searchString + "\"");
|
||||
}
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
users.add(createUser(result));
|
||||
users.add(createUser(result, domainId));
|
||||
}
|
||||
|
||||
if (users.size() == 1) {
|
||||
|
|
@ -260,28 +268,28 @@ public class OpenLdapUserManagerImpl implements LdapUserManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context) throws NamingException, IOException {
|
||||
public List<LdapUser> searchUsers(final String username, final LdapContext context, Long domainId) throws NamingException, IOException {
|
||||
|
||||
final SearchControls searchControls = new SearchControls();
|
||||
|
||||
searchControls.setSearchScope(_ldapConfiguration.getScope());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
|
||||
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes(domainId));
|
||||
|
||||
String basedn = _ldapConfiguration.getBaseDn();
|
||||
String basedn = _ldapConfiguration.getBaseDn(domainId);
|
||||
if (StringUtils.isBlank(basedn)) {
|
||||
throw new IllegalArgumentException("ldap basedn is not configured");
|
||||
}
|
||||
byte[] cookie = null;
|
||||
int pageSize = _ldapConfiguration.getLdapPageSize();
|
||||
int pageSize = _ldapConfiguration.getLdapPageSize(domainId);
|
||||
context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
|
||||
final List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
NamingEnumeration<SearchResult> results;
|
||||
do {
|
||||
results = context.search(basedn, generateSearchFilter(username), searchControls);
|
||||
results = context.search(basedn, generateSearchFilter(username, domainId), searchControls);
|
||||
while (results.hasMoreElements()) {
|
||||
final SearchResult result = results.nextElement();
|
||||
if (!isUserDisabled(result)) {
|
||||
users.add(createUser(result));
|
||||
users.add(createUser(result, domainId));
|
||||
}
|
||||
}
|
||||
Control[] contextControls = context.getResponseControls();
|
||||
|
|
|
|||
|
|
@ -23,8 +23,19 @@ import org.apache.cloudstack.ldap.LdapConfigurationVO;
|
|||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
/**
|
||||
* TODO the domain value null now searches for that specifically and there is no way to search for all domains
|
||||
*/
|
||||
public interface LdapConfigurationDao extends GenericDao<LdapConfigurationVO, Long> {
|
||||
/**
|
||||
* @deprecated there might well be more then one ldap implementation on a host and or a double binding of several domains
|
||||
* @param hostname
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
LdapConfigurationVO findByHostname(String hostname);
|
||||
|
||||
Pair<List<LdapConfigurationVO>, Integer> searchConfigurations(String hostname, int port);
|
||||
LdapConfigurationVO find(String hostname, int port, Long domainId);
|
||||
|
||||
Pair<List<LdapConfigurationVO>, Integer> searchConfigurations(String hostname, int port, Long domainId);
|
||||
}
|
||||
|
|
@ -32,7 +32,8 @@ import com.cloud.utils.db.SearchCriteria.Op;
|
|||
@Component
|
||||
public class LdapConfigurationDaoImpl extends GenericDaoBase<LdapConfigurationVO, Long> implements LdapConfigurationDao {
|
||||
private final SearchBuilder<LdapConfigurationVO> hostnameSearch;
|
||||
private final SearchBuilder<LdapConfigurationVO> listAllConfigurationsSearch;
|
||||
private final SearchBuilder<LdapConfigurationVO> listGlobalConfigurationsSearch;
|
||||
private final SearchBuilder<LdapConfigurationVO> listDomainConfigurationsSearch;
|
||||
|
||||
public LdapConfigurationDaoImpl() {
|
||||
super();
|
||||
|
|
@ -40,10 +41,16 @@ public class LdapConfigurationDaoImpl extends GenericDaoBase<LdapConfigurationVO
|
|||
hostnameSearch.and("hostname", hostnameSearch.entity().getHostname(), SearchCriteria.Op.EQ);
|
||||
hostnameSearch.done();
|
||||
|
||||
listAllConfigurationsSearch = createSearchBuilder();
|
||||
listAllConfigurationsSearch.and("hostname", listAllConfigurationsSearch.entity().getHostname(), Op.EQ);
|
||||
listAllConfigurationsSearch.and("port", listAllConfigurationsSearch.entity().getPort(), Op.EQ);
|
||||
listAllConfigurationsSearch.done();
|
||||
listGlobalConfigurationsSearch = createSearchBuilder();
|
||||
listGlobalConfigurationsSearch.and("hostname", listGlobalConfigurationsSearch.entity().getHostname(), Op.EQ);
|
||||
listGlobalConfigurationsSearch.and("port", listGlobalConfigurationsSearch.entity().getPort(), Op.EQ);
|
||||
listGlobalConfigurationsSearch.and("domain_id", listGlobalConfigurationsSearch.entity().getDomainId(),SearchCriteria.Op.NULL);
|
||||
listGlobalConfigurationsSearch.done();
|
||||
listDomainConfigurationsSearch = createSearchBuilder();
|
||||
listDomainConfigurationsSearch.and("hostname", listDomainConfigurationsSearch.entity().getHostname(), Op.EQ);
|
||||
listDomainConfigurationsSearch.and("port", listDomainConfigurationsSearch.entity().getPort(), Op.EQ);
|
||||
listDomainConfigurationsSearch.and("domain_id", listDomainConfigurationsSearch.entity().getDomainId(), Op.EQ);
|
||||
listDomainConfigurationsSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -54,11 +61,31 @@ public class LdapConfigurationDaoImpl extends GenericDaoBase<LdapConfigurationVO
|
|||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<LdapConfigurationVO>, Integer> searchConfigurations(final String hostname, final int port) {
|
||||
final SearchCriteria<LdapConfigurationVO> sc = listAllConfigurationsSearch.create();
|
||||
public LdapConfigurationVO find(String hostname, int port, Long domainId) {
|
||||
SearchCriteria<LdapConfigurationVO> sc = getSearchCriteria(hostname, port, domainId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<LdapConfigurationVO>, Integer> searchConfigurations(final String hostname, final int port, final Long domainId) {
|
||||
SearchCriteria<LdapConfigurationVO> sc = getSearchCriteria(hostname, port, domainId);
|
||||
return searchAndCount(sc, null);
|
||||
}
|
||||
|
||||
private SearchCriteria<LdapConfigurationVO> getSearchCriteria(String hostname, int port, Long domainId) {
|
||||
SearchCriteria<LdapConfigurationVO> sc;
|
||||
if (domainId == null) {
|
||||
sc = listDomainConfigurationsSearch.create();
|
||||
} else {
|
||||
sc = listDomainConfigurationsSearch.create();
|
||||
sc.setParameters("domain_id", domainId);
|
||||
}
|
||||
if (hostname != null) {
|
||||
sc.setParameters("hostname", hostname);
|
||||
}
|
||||
return searchAndCount(sc, null);
|
||||
if (port > 0) {
|
||||
sc.setParameters("port", port);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,11 @@ import org.apache.cloudstack.ldap.LdapTrustMapVO;
|
|||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface LdapTrustMapDao extends GenericDao<LdapTrustMapVO, Long> {
|
||||
LdapTrustMapVO findByDomainId(long domainId);
|
||||
LdapTrustMapVO findByAccount(long domainId, Long accountId);
|
||||
LdapTrustMapVO findGroupInDomain(long domainId, String group);
|
||||
List<LdapTrustMapVO> searchByDomainId(long domainId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,21 +26,55 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class LdapTrustMapDaoImpl extends GenericDaoBase<LdapTrustMapVO, Long> implements LdapTrustMapDao {
|
||||
private final SearchBuilder<LdapTrustMapVO> domainIdSearch;
|
||||
private final SearchBuilder<LdapTrustMapVO> groupSearch;
|
||||
|
||||
public LdapTrustMapDaoImpl() {
|
||||
super();
|
||||
domainIdSearch = createSearchBuilder();
|
||||
domainIdSearch.and("domainId", domainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
domainIdSearch.and("account_id", domainIdSearch.entity().getAccountId(),SearchCriteria.Op.EQ);
|
||||
domainIdSearch.done();
|
||||
groupSearch = createSearchBuilder();
|
||||
groupSearch.and("domainId", groupSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
|
||||
groupSearch.and("name", groupSearch.entity().getName(),SearchCriteria.Op.EQ);
|
||||
groupSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapTrustMapVO findByDomainId(long domainId) {
|
||||
final SearchCriteria<LdapTrustMapVO> sc = domainIdSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
sc.setParameters("account_id", 0);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapTrustMapVO findByAccount(long domainId, Long accountId) {
|
||||
final SearchCriteria<LdapTrustMapVO> sc = domainIdSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
sc.setParameters("account_id", accountId);
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LdapTrustMapVO findGroupInDomain(long domainId, String group){
|
||||
final SearchCriteria<LdapTrustMapVO> sc = groupSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
sc.setParameters("name", group);
|
||||
return findOneBy(sc);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LdapTrustMapVO> searchByDomainId(long domainId) {
|
||||
final SearchCriteria<LdapTrustMapVO> sc = domainIdSearch.create();
|
||||
sc.setParameters("domainId", domainId);
|
||||
return search(sc,null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@ class ADLdapUserManagerImplSpec extends spock.lang.Specification {
|
|||
|
||||
def "test getUsersInGroup null group"() {
|
||||
ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE
|
||||
ldapConfiguration.getReturnAttributes() >> ["username", "firstname", "lastname", "email"]
|
||||
ldapConfiguration.getBaseDn() >>> [null, null, "DC=cloud,DC=citrix,DC=com"]
|
||||
ldapConfiguration.getReturnAttributes(null) >> ["username", "firstname", "lastname", "email"]
|
||||
ldapConfiguration.getBaseDn(null) >>> [null, null, "DC=cloud,DC=citrix,DC=com"]
|
||||
|
||||
LdapContext context = Mock(LdapContext);
|
||||
|
||||
when:
|
||||
def result = adLdapUserManager.getUsersInGroup(group, context)
|
||||
def result = adLdapUserManager.getUsersInGroup(group, context,null)
|
||||
then:
|
||||
thrown(IllegalArgumentException)
|
||||
where:
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
def ldapUser = Mock(LdapUser)
|
||||
ldapUser.isDisabled() >> false
|
||||
ldapManager.isLdapEnabled() >> true
|
||||
ldapManager.getUser("rmurphy") >> ldapUser
|
||||
ldapManager.canAuthenticate(_, _) >> false
|
||||
ldapManager.getUser("rmurphy", null) >> ldapUser
|
||||
ldapManager.canAuthenticate(_, _, _) >> false
|
||||
|
||||
UserAccountDao userAccountDao = Mock(UserAccountDao)
|
||||
userAccountDao.getUserAccount(_, _) >> new UserAccountVO()
|
||||
|
|
@ -84,8 +84,8 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
def ldapUser = Mock(LdapUser)
|
||||
ldapUser.isDisabled() >> false
|
||||
ldapManager.isLdapEnabled() >> true
|
||||
ldapManager.canAuthenticate(_, _) >> true
|
||||
ldapManager.getUser("rmurphy") >> ldapUser
|
||||
ldapManager.canAuthenticate(_, _, _) >> true
|
||||
ldapManager.getUser("rmurphy", null) >> ldapUser
|
||||
|
||||
UserAccountDao userAccountDao = Mock(UserAccountDao)
|
||||
userAccountDao.getUserAccount(_, _) >> new UserAccountVO()
|
||||
|
|
@ -144,7 +144,7 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
userAccountDao.getUserAccount(username, domainId) >> userAccount
|
||||
userAccount.getId() >> 1
|
||||
ldapManager.getDomainLinkedToLdap(domainId) >> new LdapTrustMapVO(domainId, type, name, (short)2)
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", true)
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", true, null)
|
||||
//user should be disabled in cloudstack
|
||||
accountManager.disableUser(1) >> userAccount
|
||||
|
||||
|
|
@ -173,8 +173,8 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
ldapManager.isLdapEnabled() >> true
|
||||
userAccountDao.getUserAccount(username, domainId) >> null
|
||||
ldapManager.getDomainLinkedToLdap(domainId) >> new LdapTrustMapVO(domainId, type, name, (short)0)
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false)
|
||||
ldapManager.canAuthenticate(_,_) >> true
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false, null)
|
||||
ldapManager.canAuthenticate(_, _, _) >> true
|
||||
//user should be created in cloudstack
|
||||
accountManager.createUserAccount(username, "", "firstname", "lastname", "email", null, username, (short) 2, domainId, username, null, _, _, User.Source.LDAP) >> Mock(UserAccount)
|
||||
|
||||
|
|
@ -206,8 +206,8 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
userAccount.getId() >> 1
|
||||
userAccount.getState() >> Account.State.disabled.toString()
|
||||
ldapManager.getDomainLinkedToLdap(domainId) >> new LdapTrustMapVO(domainId, type, name, (short)2)
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false)
|
||||
ldapManager.canAuthenticate(_,_) >> true
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false, null)
|
||||
ldapManager.canAuthenticate(_, _, _) >> true
|
||||
//user should be enabled in cloudstack if disabled
|
||||
accountManager.enableUser(1) >> userAccount
|
||||
|
||||
|
|
@ -237,8 +237,8 @@ class LdapAuthenticatorSpec extends spock.lang.Specification {
|
|||
UserAccount userAccount = Mock(UserAccount)
|
||||
userAccountDao.getUserAccount(username, domainId) >> userAccount
|
||||
ldapManager.getDomainLinkedToLdap(domainId) >> new LdapTrustMapVO(domainId, type, name, (short)2)
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false)
|
||||
ldapManager.canAuthenticate(_,_) >> false
|
||||
ldapManager.getUser(username, type.toString(), name) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false, null)
|
||||
ldapManager.canAuthenticate(_, _, _) >> false
|
||||
|
||||
when:
|
||||
Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> result = ldapAuthenticator.authenticate(username, "password", domainId, null)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ class LdapConfigurationDaoImplSpec extends spock.lang.Specification {
|
|||
def "Test setting up of a LdapConfigurationDao"() {
|
||||
given: "We have an LdapConfigurationDao implementation"
|
||||
def ldapConfigurationDaoImpl = new LdapConfigurationDaoImpl();
|
||||
expect: "that hostnameSearch and listAllConfigurationsSearch is configured"
|
||||
expect: "that hostnameSearch and listDomainConfigurationsSearch is configured"
|
||||
ldapConfigurationDaoImpl.hostnameSearch != null;
|
||||
ldapConfigurationDaoImpl.listAllConfigurationsSearch != null
|
||||
ldapConfigurationDaoImpl.listDomainConfigurationsSearch != null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,55 +19,26 @@ package groovy.org.apache.cloudstack.ldap
|
|||
import org.apache.cloudstack.framework.config.ConfigKey
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import com.cloud.utils.Pair
|
||||
import org.apache.cloudstack.api.ServerApiException
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigDepotImpl
|
||||
import org.apache.cloudstack.framework.config.impl.ConfigurationVO
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration
|
||||
import org.apache.cloudstack.ldap.LdapConfigurationVO
|
||||
import org.apache.cloudstack.ldap.LdapManager
|
||||
import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDao
|
||||
import org.apache.cxf.common.util.StringUtils
|
||||
|
||||
import javax.naming.directory.SearchControls
|
||||
|
||||
class LdapConfigurationSpec extends spock.lang.Specification {
|
||||
def "Test that getAuthentication returns none"() {
|
||||
given: "We have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(ldapConfigurationDao)
|
||||
when: "Get authentication is called"
|
||||
String authentication = ldapConfiguration.getAuthentication()
|
||||
then: "none should be returned"
|
||||
authentication == "none"
|
||||
}
|
||||
|
||||
def "Test that getAuthentication returns simple"() {
|
||||
given: "We have a configDao, LdapManager and LdapConfiguration with bind principle and password set"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
configDao.getValue("ldap.bind.password") >> "password"
|
||||
configDao.getValue("ldap.bind.principal") >> "cn=rmurphy,dc=cloudstack,dc=org"
|
||||
when: "Get authentication is called"
|
||||
String authentication = ldapConfiguration.getAuthentication()
|
||||
then: "authentication should be set to simple"
|
||||
authentication == "simple"
|
||||
}
|
||||
|
||||
def "Test that getBaseDn returns dc=cloudstack,dc=org"() {
|
||||
given: "We have a ConfigDao, LdapManager and ldapConfiguration with a baseDn value set."
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.basedn") >> "dc=cloudstack,dc=org"
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
def ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
when: "Get basedn is called"
|
||||
String baseDn = ldapConfiguration.getBaseDn();
|
||||
then: "The set baseDn should be returned"
|
||||
baseDn == "dc=cloudstack,dc=org"
|
||||
}
|
||||
|
||||
def "Test that getEmailAttribute returns mail"() {
|
||||
given: "Given that we have a ConfigDao, LdapManager and LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
|
|
@ -178,87 +149,12 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
|||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the providerUrl"
|
||||
String providerUrl = ldapConfiguration.getProviderUrl()
|
||||
String providerUrl = ldapConfiguration.getProviderUrl(_)
|
||||
|
||||
then: "The providerUrl should be given."
|
||||
providerUrl == "ldap://localhost:389"
|
||||
}
|
||||
|
||||
def "Test that get search group principle returns successfully"() {
|
||||
given: "We have a ConfigDao with a value for ldap.search.group.principle and an LdapConfiguration"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.search.group.principle") >> "cn=cloudstack,cn=users,dc=cloudstack,dc=org"
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the search group principle"
|
||||
String result = ldapConfiguration.getSearchGroupPrinciple();
|
||||
|
||||
then: "The result holds the same value configDao did"
|
||||
result == "cn=cloudstack,cn=users,dc=cloudstack,dc=org"
|
||||
}
|
||||
|
||||
def "Test that getTrustStorePassword resopnds"() {
|
||||
given: "We have a ConfigDao with a value for truststore password"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.truststore.password") >> "password"
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the truststore password"
|
||||
String result = ldapConfiguration.getTrustStorePassword()
|
||||
|
||||
then: "The result is password"
|
||||
result == "password";
|
||||
}
|
||||
|
||||
def "Test that getSSLStatus can be true"() {
|
||||
given: "We have a ConfigDao with values for truststore and truststore password set"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.truststore") >> "/tmp/ldap.ts"
|
||||
configDao.getValue("ldap.truststore.password") >> "password"
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
|
||||
when: "A request is made to get the status of SSL"
|
||||
boolean result = ldapConfiguration.getSSLStatus();
|
||||
|
||||
then: "The response should be true"
|
||||
result == true
|
||||
}
|
||||
|
||||
def "Test getgroupobject"() {
|
||||
given: "We have configdao for ldap group object"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.group.object") >> groupObject
|
||||
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
def expectedResult = groupObject == null ? "groupOfUniqueNames" : groupObject
|
||||
|
||||
def result = ldapConfiguration.getGroupObject()
|
||||
expect:
|
||||
result == expectedResult
|
||||
where:
|
||||
groupObject << [null, "", "groupOfUniqueNames"]
|
||||
}
|
||||
|
||||
def "Test getGroupUniqueMemeberAttribute"() {
|
||||
given: "We have configdao for ldap group object"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
configDao.getValue("ldap.group.user.uniquemember") >> groupObject
|
||||
|
||||
def ldapConfigurationDao = Mock(LdapConfigurationDao)
|
||||
LdapConfiguration ldapConfiguration = new LdapConfiguration(configDao, ldapConfigurationDao)
|
||||
def expectedResult = groupObject == null ? "uniquemember" : groupObject
|
||||
|
||||
def result = ldapConfiguration.getGroupUniqueMemeberAttribute()
|
||||
expect:
|
||||
result == expectedResult
|
||||
where:
|
||||
groupObject << [null, "", "uniquemember"]
|
||||
}
|
||||
|
||||
def "Test getReadTimeout"() {
|
||||
given: "We have configdao for ldap group object"
|
||||
def configDao = Mock(ConfigurationDao)
|
||||
|
|
@ -275,7 +171,7 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
|||
|
||||
def expected = timeout == null ? 1000 : timeout.toLong() //1000 is the default value
|
||||
|
||||
def result = ldapConfiguration.getReadTimeout()
|
||||
def result = ldapConfiguration.getReadTimeout(null)
|
||||
expect:
|
||||
result == expected
|
||||
where:
|
||||
|
|
@ -298,7 +194,7 @@ class LdapConfigurationSpec extends spock.lang.Specification {
|
|||
|
||||
def expected = provider.equalsIgnoreCase("microsoftad") ? LdapUserManager.Provider.MICROSOFTAD : LdapUserManager.Provider.OPENLDAP //"openldap" is the default value
|
||||
|
||||
def result = ldapConfiguration.getLdapProvider()
|
||||
def result = ldapConfiguration.getLdapProvider(null)
|
||||
expect:
|
||||
println "asserting for provider configuration: " + provider
|
||||
result == expected
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import spock.lang.Shared
|
|||
|
||||
import javax.naming.NamingException
|
||||
import javax.naming.directory.SearchControls
|
||||
import javax.naming.ldap.LdapContext
|
||||
|
||||
class LdapContextFactorySpec extends spock.lang.Specification {
|
||||
@Shared
|
||||
|
|
@ -41,7 +40,7 @@ class LdapContextFactorySpec extends spock.lang.Specification {
|
|||
ldapConfiguration = Mock(LdapConfiguration)
|
||||
|
||||
ldapConfiguration.getFactory() >> "com.sun.jndi.ldap.LdapCtxFactory"
|
||||
ldapConfiguration.getProviderUrl() >> "ldap://localhost:389"
|
||||
ldapConfiguration.getProviderUrl(_) >> "ldap://localhost:389"
|
||||
ldapConfiguration.getAuthentication() >> "none"
|
||||
ldapConfiguration.getScope() >> SearchControls.SUBTREE_SCOPE
|
||||
ldapConfiguration.getReturnAttributes() >> ["uid", "mail", "cn"]
|
||||
|
|
@ -49,11 +48,11 @@ class LdapContextFactorySpec extends spock.lang.Specification {
|
|||
ldapConfiguration.getEmailAttribute() >> "mail"
|
||||
ldapConfiguration.getFirstnameAttribute() >> "givenname"
|
||||
ldapConfiguration.getLastnameAttribute() >> "sn"
|
||||
ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org"
|
||||
ldapConfiguration.getBaseDn(_) >> "dc=cloudstack,dc=org"
|
||||
ldapConfiguration.getSSLStatus() >> true
|
||||
ldapConfiguration.getTrustStore() >> "/tmp/ldap.ts"
|
||||
ldapConfiguration.getTrustStorePassword() >> "password"
|
||||
ldapConfiguration.getReadTimeout() >> 1000
|
||||
ldapConfiguration.getReadTimeout(_) >> 1000
|
||||
ldapConfiguration.getLdapPageSize() >> 1
|
||||
|
||||
username = "rmurphy"
|
||||
|
|
@ -87,7 +86,7 @@ class LdapContextFactorySpec extends spock.lang.Specification {
|
|||
def result = ldapContextFactory.getEnvironment(null, null, null, true)
|
||||
|
||||
then: "The resulting values should be set"
|
||||
result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl()
|
||||
result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl(null)
|
||||
result['java.naming.factory.initial'] == ldapConfiguration.getFactory()
|
||||
result['java.naming.security.principal'] == null
|
||||
result['java.naming.security.authentication'] == ldapConfiguration.getAuthentication()
|
||||
|
|
@ -102,7 +101,7 @@ class LdapContextFactorySpec extends spock.lang.Specification {
|
|||
def result = ldapContextFactory.getEnvironment(principal, password, null, false)
|
||||
|
||||
then: "The resulting values should be set"
|
||||
result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl()
|
||||
result['java.naming.provider.url'] == ldapConfiguration.getProviderUrl(null)
|
||||
result['java.naming.factory.initial'] == ldapConfiguration.getFactory()
|
||||
result['java.naming.security.principal'] == principal
|
||||
result['java.naming.security.authentication'] == "simple"
|
||||
|
|
|
|||
|
|
@ -16,54 +16,13 @@
|
|||
// under the License.
|
||||
package groovy.org.apache.cloudstack.ldap
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException
|
||||
import org.apache.cloudstack.api.ServerApiException
|
||||
import org.apache.cloudstack.api.command.LdapAddConfigurationCmd
|
||||
import org.apache.cloudstack.api.response.LdapConfigurationResponse
|
||||
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
|
||||
import org.apache.cloudstack.api.command.LdapCreateAccountCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserAccountVO
|
||||
import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
|
||||
|
||||
import javax.naming.NamingException
|
||||
import org.apache.cloudstack.api.command.LdapCreateAccountCmd
|
||||
import com.cloud.user.AccountService
|
||||
|
||||
class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
||||
|
||||
def "Test failure to retrive LDAP user"() {
|
||||
given: "We have an LdapManager, AccountService and LdapCreateAccountCmd and LDAP user that doesn't exist"
|
||||
LdapManager ldapManager = Mock(LdapManager)
|
||||
ldapManager.getUser(_) >> { throw new NoLdapUserMatchingQueryException() }
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = Spy(LdapCreateAccountCmd, constructorArgs: [ldapManager, accountService])
|
||||
ldapCreateAccountCmd.getCurrentContext() >> Mock(CallContext)
|
||||
CallContext context = ldapCreateAccountCmd.getCurrentContext()
|
||||
when: "An an account is created"
|
||||
ldapCreateAccountCmd.execute()
|
||||
then: "It fails and an exception is thrown"
|
||||
thrown ServerApiException
|
||||
}
|
||||
|
||||
def "Test failed creation due to a null response from cloudstack account creater"() {
|
||||
given: "We have an LdapManager, AccountService and LdapCreateAccountCmd"
|
||||
LdapManager ldapManager = Mock(LdapManager)
|
||||
ldapManager.getUser(_) >> new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false)
|
||||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = Spy(LdapCreateAccountCmd, constructorArgs: [ldapManager, accountService])
|
||||
ldapCreateAccountCmd.getCurrentContext() >> Mock(CallContext)
|
||||
ldapCreateAccountCmd.createCloudstackUserAccount(_, _, _) >> null
|
||||
when: "Cloudstack fail to create the user"
|
||||
ldapCreateAccountCmd.execute()
|
||||
then: "An exception is thrown"
|
||||
thrown ServerApiException
|
||||
}
|
||||
|
||||
def "Test command name"() {
|
||||
given: "We have an LdapManager, AccountService and LdapCreateAccountCmd"
|
||||
LdapManager ldapManager = Mock(LdapManager)
|
||||
|
|
@ -105,7 +64,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
|||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService);
|
||||
when: "a user with an username, email, firstname and lastname is validated"
|
||||
def result = ldapCreateAccountCmd.validateUser(new LdapUser("username", "email", "firstname", "lastname", "principal", "domain", false))
|
||||
def result = ldapCreateAccountCmd.validateUser(new LdapUser("username", "email", "firstname", "lastname", "principal", "domain", false, null))
|
||||
then: "the result is true"
|
||||
result == true
|
||||
}
|
||||
|
|
@ -116,7 +75,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
|||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService)
|
||||
when: "A user with no email address attempts to validate"
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username", null, "firstname", "lastname", "principal", "domain", false))
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username", null, "firstname", "lastname", "principal", "domain", false, null))
|
||||
then: "An exception is thrown"
|
||||
thrown Exception
|
||||
}
|
||||
|
|
@ -138,7 +97,7 @@ class LdapCreateAccountCmdSpec extends spock.lang.Specification {
|
|||
AccountService accountService = Mock(AccountService)
|
||||
def ldapCreateAccountCmd = new LdapCreateAccountCmd(ldapManager, accountService)
|
||||
when: "A user with no lastname attempts to validate"
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username", "email", "firstname", null, "principal", "domain", false))
|
||||
ldapCreateAccountCmd.validateUser(new LdapUser("username", "email", "firstname", null, "principal", "domain", false, null))
|
||||
then: "An exception is thown"
|
||||
thrown Exception
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class LdapDeleteConfigurationCmdSpec extends spock.lang.Specification {
|
|||
def "Test failed response from execute"() {
|
||||
given: "We have an LdapManager and LdapDeleteConfigurationCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
ldapManager.deleteConfiguration(_) >> { throw new InvalidParameterValueException() }
|
||||
ldapManager.deleteConfiguration(_, 0, null) >> { throw new InvalidParameterValueException() }
|
||||
def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager)
|
||||
when:"LdapDeleteConfigurationCmd is executed and no configuration exists"
|
||||
ldapDeleteConfigurationCmd.execute()
|
||||
|
|
@ -48,7 +48,7 @@ class LdapDeleteConfigurationCmdSpec extends spock.lang.Specification {
|
|||
def "Test successful response from execute"() {
|
||||
given: "We have an LdapManager and LdapDeleteConfigurationCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
ldapManager.deleteConfiguration(_) >> new LdapConfigurationResponse("localhost")
|
||||
ldapManager.deleteConfiguration(_, 0, null) >> new LdapConfigurationResponse("localhost")
|
||||
def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager)
|
||||
when: "LdapDeleteConfigurationCmd is executed"
|
||||
ldapDeleteConfigurationCmd.execute()
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ import com.cloud.user.DomainService
|
|||
import com.cloud.user.User
|
||||
import com.cloud.user.UserAccountVO
|
||||
import com.cloud.user.UserVO
|
||||
import org.apache.cloudstack.api.command.LdapCreateAccountCmd
|
||||
import org.apache.cloudstack.api.command.LdapImportUsersCmd
|
||||
import org.apache.cloudstack.api.response.LdapUserResponse
|
||||
import org.apache.cloudstack.context.CallContext
|
||||
import org.apache.cloudstack.ldap.LdapManager
|
||||
import org.apache.cloudstack.ldap.LdapUser
|
||||
|
||||
|
|
@ -53,9 +51,9 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> [response1, response2]
|
||||
|
|
@ -81,9 +79,9 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsersInGroup("TestGroup") >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsersInGroup("TestGroup", null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> [response1, response2]
|
||||
|
|
@ -110,9 +108,9 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsersInGroup("TestGroup") >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsersInGroup("TestGroup", null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> [response1, response2]
|
||||
|
|
@ -139,9 +137,9 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
def accountService = Mock(AccountService)
|
||||
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> [response1, response2]
|
||||
|
|
@ -169,8 +167,8 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
ldapImportUsersCmd.domainId = varDomainId
|
||||
ldapImportUsersCmd.groupName = varGroupName
|
||||
|
||||
def ldapUser1 = new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false)
|
||||
def ldapUser2 = new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false);
|
||||
def ldapUser1 = new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null)
|
||||
def ldapUser2 = new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null);
|
||||
|
||||
Domain domain = new DomainVO(expectedDomainName, 1L, 1L, expectedDomainName, UUID.randomUUID().toString());
|
||||
if (varDomainId != null) {
|
||||
|
|
@ -204,8 +202,8 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> response1
|
||||
|
||||
|
|
@ -234,8 +232,8 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> response1
|
||||
|
||||
|
|
@ -263,8 +261,8 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
|
|||
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")
|
||||
ldapManager.createLdapUserResponse(_) >>> response1
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class LdapListUsersCmdSpec extends spock.lang.Specification {
|
|||
def "Test successful empty response from execute"() {
|
||||
given: "We have a LdapManager with no users, QueryService and a LdapListUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
ldapManager.getUsers() >> {throw new NoLdapUserMatchingQueryException()}
|
||||
ldapManager.getUsers(null) >> {throw new NoLdapUserMatchingQueryException()}
|
||||
def queryService = Mock(QueryService)
|
||||
def ldapListUsersCmd = new LdapListUsersCmd(ldapManager, queryService)
|
||||
when: "LdapListUsersCmd is executed"
|
||||
|
|
@ -53,8 +53,8 @@ class LdapListUsersCmdSpec extends spock.lang.Specification {
|
|||
given: "We have an LdapManager, one user, QueryService and a LdapListUsersCmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false))
|
||||
ldapManager.getUsers() >> users
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null))
|
||||
ldapManager.getUsers(null) >> users
|
||||
LdapUserResponse response = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null)
|
||||
ldapManager.createLdapUserResponse(_) >> response
|
||||
def queryService = Mock(QueryService)
|
||||
|
|
@ -92,7 +92,7 @@ class LdapListUsersCmdSpec extends spock.lang.Specification {
|
|||
|
||||
queryService.searchForUsers(_) >> queryServiceResponse
|
||||
|
||||
def ldapUser = new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false)
|
||||
def ldapUser = new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null)
|
||||
def ldapListUsersCmd = new LdapListUsersCmd(ldapManager,queryService)
|
||||
|
||||
when: "isACloudstackUser is executed"
|
||||
|
|
@ -109,7 +109,7 @@ class LdapListUsersCmdSpec extends spock.lang.Specification {
|
|||
|
||||
queryService.searchForUsers(_) >> new ListResponse<UserResponse>()
|
||||
|
||||
def ldapUser = new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false)
|
||||
def ldapUser = new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null)
|
||||
def ldapListUsersCmd = new LdapListUsersCmd(ldapManager,queryService)
|
||||
|
||||
when: "isACloudstackUser is executed"
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapContextFactory.createBindContext() >> { throw new NoLdapUserMatchingQueryException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a user but there is a bind issue"
|
||||
ldapManager.getUser("rmurphy")
|
||||
ldapManager.getUser("rmurphy", null)
|
||||
then: "an exception is thrown"
|
||||
thrown NoLdapUserMatchingQueryException
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapContextFactory.createBindContext() >> { throw new NamingException() }
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users but there is a bind issue"
|
||||
ldapManager.getUsers()
|
||||
ldapManager.getUsers(null)
|
||||
then: "An exception is thrown"
|
||||
thrown NoLdapUserMatchingQueryException
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap user response is generated"
|
||||
def result = ldapManager.createLdapUserResponse(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org",
|
||||
"engineering", false))
|
||||
"engineering", false, null))
|
||||
then: "The result of the response should match the given ldap user"
|
||||
result.username == "rmurphy"
|
||||
result.email == "rmurphy@test.com"
|
||||
|
|
@ -136,11 +136,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
List<LdapUser> users = new ArrayList<>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false))
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null))
|
||||
ldapUserManager.getUsers(_) >> users;
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users"
|
||||
def result = ldapManager.getUsers()
|
||||
def result = ldapManager.getUsers(null)
|
||||
then: "A list greater than 0 is returned"
|
||||
result.size() > 0;
|
||||
}
|
||||
|
|
@ -154,10 +154,10 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
ldapUserManager.getUser(_, _) >> new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false)
|
||||
ldapUserManager.getUser(_, _, _) >> new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null)
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a user"
|
||||
def result = ldapManager.getUser("rmurphy")
|
||||
def result = ldapManager.getUser("rmurphy", null)
|
||||
then: "The user is returned"
|
||||
result.username == "rmurphy"
|
||||
result.email == "rmurphy@test.com"
|
||||
|
|
@ -192,9 +192,9 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
|
||||
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
ldapManager.getUser(_, null) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
when: "The user attempts to authenticate with a bad password"
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password")
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password", null)
|
||||
then: "The authentication fails"
|
||||
result == false
|
||||
}
|
||||
|
|
@ -210,7 +210,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapConfigurationDao.findByHostname(_) >> null
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration that doesn't exist is deleted"
|
||||
ldapManager.deleteConfiguration("localhost")
|
||||
ldapManager.deleteConfiguration("localhost", 0, null)
|
||||
then: "A exception is thrown"
|
||||
thrown InvalidParameterValueException
|
||||
}
|
||||
|
|
@ -242,9 +242,9 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
def ldapConfiguration = Mock(LdapConfiguration)
|
||||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
def ldapManager = Spy(LdapManagerImpl, constructorArgs: [ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration])
|
||||
ldapManager.getUser(_) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
ldapManager.getUser(_, null) >> { new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null) }
|
||||
when: "A user authenticates"
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password")
|
||||
def result = ldapManager.canAuthenticate("rmurphy", "password", null)
|
||||
then: "The result is true"
|
||||
result == true
|
||||
}
|
||||
|
|
@ -265,7 +265,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapConfigurationDao.remove(_) >> null
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "A ldap configuration is deleted"
|
||||
def result = ldapManager.deleteConfiguration("localhost")
|
||||
def result = ldapManager.deleteConfiguration("localhost", 0, null)
|
||||
then: "The deleted configuration is returned"
|
||||
result.hostname == "localhost"
|
||||
result.port == 389
|
||||
|
|
@ -282,7 +282,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapContextFactory.createBindContext() >> null;
|
||||
|
||||
List<LdapUser> users = new ArrayList<LdapUser>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapUserManager.getUsers(_, _) >> users;
|
||||
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
|
|
@ -424,11 +424,11 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
ldapUserManagerFactory.getInstance(_) >> ldapUserManager
|
||||
ldapContextFactory.createBindContext() >> null
|
||||
List<LdapUser> users = new ArrayList<>();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", "engineering", false))
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", "engineering", false, null))
|
||||
ldapUserManager.getUsersInGroup("engineering", _) >> users;
|
||||
def ldapManager = new LdapManagerImpl(ldapConfigurationDao, ldapContextFactory, ldapUserManagerFactory, ldapConfiguration)
|
||||
when: "We search for a group of users"
|
||||
def result = ldapManager.getUsersInGroup("engineering")
|
||||
def result = ldapManager.getUsersInGroup("engineering", null)
|
||||
then: "A list greater of size one is returned"
|
||||
result.size() == 1;
|
||||
}
|
||||
|
|
@ -524,7 +524,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
def type = "GROUP"
|
||||
def name = "CN=test,DC=citrix,DC=com"
|
||||
|
||||
ldapUserManager.getUser(username, type, name, _) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", true)
|
||||
ldapUserManager.getUser(username, type, name, _) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", true, null)
|
||||
|
||||
when:
|
||||
LdapUser user = ldapManager.getUser(username, type, name)
|
||||
|
|
@ -574,7 +574,7 @@ class LdapManagerImplSpec extends spock.lang.Specification {
|
|||
def type = "GROUP"
|
||||
def name = "CN=test,DC=citrix,DC=com"
|
||||
|
||||
ldapUserManager.getUser(username, type, name, _) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false)
|
||||
ldapUserManager.getUser(username, type, name, _) >> new LdapUser(username, "email", "firstname", "lastname", "principal", "domain", false, null)
|
||||
|
||||
when:
|
||||
LdapUser user = ldapManager.getUser(username, type, name)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class LdapSearchUserCmdSpec extends spock.lang.Specification {
|
|||
given: "We have an Ldap manager and ldap user search cmd"
|
||||
def ldapManager = Mock(LdapManager)
|
||||
List<LdapUser> users = new ArrayList()
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false))
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null, false, null))
|
||||
ldapManager.searchUsers(_) >> users
|
||||
LdapUserResponse response = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,dc=cloudstack,dc=org", null)
|
||||
ldapManager.createLdapUserResponse(_) >> response
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing LdapUsers hashCode generation"() {
|
||||
given:
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false)
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false, null)
|
||||
expect:
|
||||
userA.hashCode() == usernameA.hashCode()
|
||||
where:
|
||||
|
|
@ -31,8 +31,8 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing that LdapUser successfully gives the correct result for a compare to"() {
|
||||
given: "You have created two LDAP user objects"
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false)
|
||||
def userB = new LdapUser(usernameB, "", "", "", "", "", false)
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false, null)
|
||||
def userB = new LdapUser(usernameB, "", "", "", "", "", false, null)
|
||||
expect: "That when compared the result is less than or equal to 0"
|
||||
userA.compareTo(userB) <= 0
|
||||
where: "The following values are used"
|
||||
|
|
@ -43,8 +43,8 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing that LdapUsers equality"() {
|
||||
given:
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false)
|
||||
def userB = new LdapUser(usernameB, "", "", "", "", "", false)
|
||||
def userA = new LdapUser(usernameA, "", "", "", "", "", false, null)
|
||||
def userB = new LdapUser(usernameB, "", "", "", "", "", false, null)
|
||||
expect:
|
||||
userA.equals(userA) == true
|
||||
userA.equals(new Object()) == false
|
||||
|
|
@ -56,7 +56,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing that the username is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a username"
|
||||
def user = new LdapUser(username, "", "", "", "", "", false)
|
||||
def user = new LdapUser(username, "", "", "", "", "", false, null)
|
||||
expect: "The username is equal to the given data source"
|
||||
user.getUsername() == username
|
||||
where: "The username is set to "
|
||||
|
|
@ -65,7 +65,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing the email is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a email"
|
||||
def user = new LdapUser("", email, "", "", "", "", false)
|
||||
def user = new LdapUser("", email, "", "", "", "", false, null)
|
||||
expect: "The email is equal to the given data source"
|
||||
user.getEmail() == email
|
||||
where: "The email is set to "
|
||||
|
|
@ -74,7 +74,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing the firstname is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a firstname"
|
||||
def user = new LdapUser("", "", firstname, "", "", "", false)
|
||||
def user = new LdapUser("", "", firstname, "", "", "", false, null)
|
||||
expect: "The firstname is equal to the given data source"
|
||||
user.getFirstname() == firstname
|
||||
where: "The firstname is set to "
|
||||
|
|
@ -83,7 +83,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing the lastname is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a lastname"
|
||||
def user = new LdapUser("", "", "", lastname, "", "", false)
|
||||
def user = new LdapUser("", "", "", lastname, "", "", false, null)
|
||||
expect: "The lastname is equal to the given data source"
|
||||
user.getLastname() == lastname
|
||||
where: "The lastname is set to "
|
||||
|
|
@ -92,7 +92,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing the principal is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a principal"
|
||||
def user = new LdapUser("", "", "", "", principal, "", false)
|
||||
def user = new LdapUser("", "", "", "", principal, "", false, null)
|
||||
expect: "The principal is equal to the given data source"
|
||||
user.getPrincipal() == principal
|
||||
where: "The principal is set to "
|
||||
|
|
@ -101,7 +101,7 @@ class LdapUserSpec extends spock.lang.Specification {
|
|||
|
||||
def "Testing the domain is correctly set with the ldap object"() {
|
||||
given: "You have created a LDAP user object with a principal"
|
||||
def user = new LdapUser("", "", "", "", "", domain, false)
|
||||
def user = new LdapUser("", "", "", "", "", domain, false, null)
|
||||
expect: "The principal is equal to the given data source"
|
||||
user.getDomain() == domain
|
||||
where: "The username is set to "
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class LinkDomainToLdapCmdSpec extends Specification {
|
|||
|
||||
LinkDomainToLdapResponse response = new LinkDomainToLdapResponse(domainId, type, name, (short)accountType)
|
||||
_ldapManager.linkDomainToLdap(_,_,_,_) >> response
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", true)
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", true, null)
|
||||
|
||||
linkDomainToLdapCmd.admin = username
|
||||
linkDomainToLdapCmd.type = type
|
||||
|
|
@ -107,7 +107,7 @@ class LinkDomainToLdapCmdSpec extends Specification {
|
|||
|
||||
LinkDomainToLdapResponse response = new LinkDomainToLdapResponse(domainId.toString(), type, name, (short)accountType)
|
||||
_ldapManager.linkDomainToLdap(_,_,_,_) >> response
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", false)
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", false, null)
|
||||
|
||||
_accountService.getActiveAccountByName(username, domainId) >> Mock(Account)
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ class LinkDomainToLdapCmdSpec extends Specification {
|
|||
|
||||
LinkDomainToLdapResponse response = new LinkDomainToLdapResponse(domainId.toString(), type, name, (short)accountType)
|
||||
_ldapManager.linkDomainToLdap(_,_,_,_) >> response
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", false)
|
||||
_ldapManager.getUser(username, type, name) >> new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", name, "ccp", false, null)
|
||||
|
||||
_accountService.getActiveAccountByName(username, domainId) >> null
|
||||
UserAccount userAccount = Mock(UserAccount)
|
||||
|
|
|
|||
|
|
@ -17,14 +17,12 @@
|
|||
package groovy.org.apache.cloudstack.ldap
|
||||
|
||||
import org.apache.cloudstack.ldap.LdapConfiguration
|
||||
import org.apache.cloudstack.ldap.LdapUserManager
|
||||
import org.apache.cloudstack.ldap.OpenLdapUserManagerImpl
|
||||
import spock.lang.Shared
|
||||
|
||||
import javax.naming.NamingException
|
||||
import javax.naming.directory.Attribute
|
||||
import javax.naming.directory.Attributes
|
||||
import javax.naming.directory.InitialDirContext
|
||||
import javax.naming.directory.SearchControls
|
||||
import javax.naming.directory.SearchResult
|
||||
import javax.naming.ldap.InitialLdapContext
|
||||
|
|
@ -167,12 +165,12 @@ class OpenLdapUserManagerSpec extends spock.lang.Specification {
|
|||
ldapConfiguration.getEmailAttribute() >> "mail"
|
||||
ldapConfiguration.getFirstnameAttribute() >> "givenname"
|
||||
ldapConfiguration.getLastnameAttribute() >> "sn"
|
||||
ldapConfiguration.getBaseDn() >> "dc=cloudstack,dc=org"
|
||||
ldapConfiguration.getBaseDn(_) >> "dc=cloudstack,dc=org"
|
||||
ldapConfiguration.getCommonNameAttribute() >> "cn"
|
||||
ldapConfiguration.getGroupObject() >> "groupOfUniqueNames"
|
||||
ldapConfiguration.getGroupUniqueMemeberAttribute() >> "uniquemember"
|
||||
ldapConfiguration.getGroupUniqueMemberAttribute(_) >> "uniquemember"
|
||||
ldapConfiguration.getLdapPageSize() >> 1
|
||||
ldapConfiguration.getReadTimeout() >> 1000
|
||||
ldapConfiguration.getReadTimeout(_) >> 1000
|
||||
|
||||
username = "rmurphy"
|
||||
email = "rmurphy@test.com"
|
||||
|
|
@ -186,7 +184,7 @@ class OpenLdapUserManagerSpec extends spock.lang.Specification {
|
|||
def attributes = createUserAttributes(username, email, firstname, lastname)
|
||||
def search = createSearchResult(attributes)
|
||||
def userManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
def result = userManager.createUser(search)
|
||||
def result = userManager.createUser(search,)
|
||||
|
||||
expect: "The crated user the data supplied from LDAP"
|
||||
|
||||
|
|
@ -290,7 +288,7 @@ class OpenLdapUserManagerSpec extends spock.lang.Specification {
|
|||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextOneUser())
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextOneUser(),)
|
||||
then: "one user is returned"
|
||||
result.size() == 1
|
||||
}
|
||||
|
|
@ -300,7 +298,7 @@ class OpenLdapUserManagerSpec extends spock.lang.Specification {
|
|||
def ldapUserManager = new OpenLdapUserManagerImpl(ldapConfiguration)
|
||||
|
||||
when: "A request for users is made"
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextNoUser())
|
||||
def result = ldapUserManager.getUsersInGroup("engineering", createGroupSearchContextNoUser(),)
|
||||
then: "no user is returned"
|
||||
result.size() == 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
// 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.cloudstack.api.command;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
interface LdapConfigurationChanger {
|
||||
/**
|
||||
* sets a possibly not accessible field of the target object.
|
||||
* @param target the object to set a hidden fields value in.
|
||||
* @param name the name of the field to set.
|
||||
* @param o intended value for the field "name"
|
||||
* @throws IllegalAccessException
|
||||
* @throws NoSuchFieldException
|
||||
*/
|
||||
default void setHiddenField(Object target, final String name, final Object o) throws IllegalAccessException, NoSuchFieldException {
|
||||
Class<?> klas = target.getClass();
|
||||
Field f = getFirstFoundField(name, klas);
|
||||
f.setAccessible(true);
|
||||
f.set(target, o);
|
||||
}
|
||||
|
||||
/**
|
||||
* the first field found by this name in the class "klas" or any of it's superclasses except for {@code Object}. Implementers of this interface can decide to also return any field in implemented interfaces or in {@code Object}.
|
||||
*
|
||||
* @param name of the field to find
|
||||
* @param klas class to gat a field by name "name" from
|
||||
* @return a {@code Field} by the name "name"
|
||||
* @throws NoSuchFieldException
|
||||
*/
|
||||
default Field getFirstFoundField(String name, Class<?> klas) throws NoSuchFieldException {
|
||||
try {
|
||||
return klas.getDeclaredField(name);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Class<?> parent = klas.getSuperclass();
|
||||
if(parent.equals(Object.class)) {
|
||||
throw e;
|
||||
}
|
||||
return getFirstFoundField(name, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
// 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.cloudstack.api.command;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.apache.cloudstack.ldap.NoLdapUserMatchingQueryException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.powermock.api.mockito.PowerMockito.spy;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LdapCreateAccountCmdTest implements LdapConfigurationChanger {
|
||||
@Mock
|
||||
LdapManager ldapManager;
|
||||
@Mock
|
||||
AccountService accountService;
|
||||
@Mock
|
||||
RoleService roleService;
|
||||
|
||||
LdapCreateAccountCmd ldapCreateAccountCmd;
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
ldapCreateAccountCmd = spy(new LdapCreateAccountCmd(ldapManager, accountService));
|
||||
ldapCreateAccountCmd.roleService = roleService;
|
||||
setHiddenField(ldapCreateAccountCmd,"accountType", Account.ACCOUNT_TYPE_DOMAIN_ADMIN);
|
||||
}
|
||||
|
||||
@Test(expected = ServerApiException.class)
|
||||
public void failureToRetrieveLdapUser() throws Exception {
|
||||
// We have an LdapManager, AccountService and LdapCreateAccountCmd and LDAP user that doesn't exist
|
||||
when(ldapManager.getUser(anyString(), isNull(Long.class))).thenThrow(NoLdapUserMatchingQueryException.class);
|
||||
ldapCreateAccountCmd.execute();
|
||||
fail("An exception should have been thrown: " + ServerApiException.class);
|
||||
}
|
||||
|
||||
@Test(expected = ServerApiException.class)
|
||||
public void failedCreationDueToANullResponseFromCloudstackAccountCreater() throws Exception {
|
||||
// We have an LdapManager, AccountService and LdapCreateAccountCmd
|
||||
LdapUser mrMurphy = new LdapUser("rmurphy", "rmurphy@cloudstack.org", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null);
|
||||
when(ldapManager.getUser(anyString(), isNull(Long.class))).thenReturn(mrMurphy);
|
||||
ldapCreateAccountCmd.execute();
|
||||
fail("An exception should have been thrown: " + ServerApiException.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// 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.cloudstack.api.command;
|
||||
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.DomainService;
|
||||
import org.apache.cloudstack.acl.RoleService;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.apache.cloudstack.api.response.LdapUserResponse;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.powermock.api.mockito.PowerMockito.spy;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LdapImportUsersCmdTest implements LdapConfigurationChanger {
|
||||
@Mock
|
||||
LdapManager ldapManager;
|
||||
@Mock
|
||||
AccountService accountService;
|
||||
@Mock
|
||||
DomainService domainService;
|
||||
@Mock
|
||||
RoleService roleService;
|
||||
|
||||
LdapImportUsersCmd ldapImportUsersCmd;
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
ldapImportUsersCmd = spy(new LdapImportUsersCmd(ldapManager, domainService, accountService));
|
||||
ldapImportUsersCmd.roleService = roleService;
|
||||
setHiddenField(ldapImportUsersCmd, "accountType", Account.ACCOUNT_TYPE_DOMAIN_ADMIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void successfulResponseFromExecute() throws Exception {
|
||||
List<LdapUser> users = new ArrayList();
|
||||
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null));
|
||||
users.add(new LdapUser("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering", false, null));
|
||||
when(ldapManager.getUsers(null)).thenReturn(users);
|
||||
LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering");
|
||||
LdapUserResponse response2 = new LdapUserResponse("bob", "bob@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering");
|
||||
when(ldapManager.createLdapUserResponse(any(LdapUser.class))).thenReturn(response1).thenReturn(response2);
|
||||
|
||||
|
||||
Domain domain = new DomainVO("engineering", 1L, 1L, "engineering", UUID.randomUUID().toString());
|
||||
when(domainService.getDomainByName("engineering", 1L)).thenReturn(null, domain);
|
||||
when(domainService.createDomain(eq("engineering"), eq(1L), eq("engineering"), anyString())).thenReturn(domain);
|
||||
|
||||
ldapImportUsersCmd.execute();
|
||||
ListResponse<LdapUserResponse> resp = (ListResponse<LdapUserResponse>)ldapImportUsersCmd.getResponseObject();
|
||||
assertEquals(" when LdapListUsersCmd is executed, a list of size 2 should be returned", 2, resp.getResponses().size());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// 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.cloudstack.api.command;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccountVO;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.response.LinkAccountToLdapResponse;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LinkAccountToLdapCmdTest implements LdapConfigurationChanger {
|
||||
|
||||
@Mock
|
||||
LdapManager ldapManager;
|
||||
@Mock
|
||||
AccountService accountService;
|
||||
|
||||
LinkAccountToLdapCmd linkAccountToLdapCmd;
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
linkAccountToLdapCmd = new LinkAccountToLdapCmd();
|
||||
setHiddenField(linkAccountToLdapCmd, "_ldapManager", ldapManager);
|
||||
setHiddenField(linkAccountToLdapCmd, "_accountService", accountService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void execute() throws Exception {
|
||||
// test with valid params and with admin who doesnt exist in cloudstack
|
||||
long domainId = 1;
|
||||
String type = "GROUP";
|
||||
String ldapDomain = "CN=test,DC=ccp,DC=Citrix,DC=com";
|
||||
short accountType = Account.ACCOUNT_TYPE_DOMAIN_ADMIN;
|
||||
String username = "admin";
|
||||
long accountId = 24;
|
||||
String accountName = "test";
|
||||
|
||||
setHiddenField(linkAccountToLdapCmd, "ldapDomain", ldapDomain);
|
||||
setHiddenField(linkAccountToLdapCmd, "admin", username);
|
||||
setHiddenField(linkAccountToLdapCmd, "type", type);
|
||||
setHiddenField(linkAccountToLdapCmd, "domainId", domainId);
|
||||
setHiddenField(linkAccountToLdapCmd, "accountType", accountType);
|
||||
setHiddenField(linkAccountToLdapCmd, "accountName", accountName);
|
||||
|
||||
|
||||
LinkAccountToLdapResponse response = new LinkAccountToLdapResponse(String.valueOf(domainId), type, ldapDomain, (short)accountType, username, accountName);
|
||||
when(ldapManager.linkAccountToLdap(linkAccountToLdapCmd)).thenReturn(response);
|
||||
when(ldapManager.getUser(username, type, ldapDomain, 1L))
|
||||
.thenReturn(new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", ldapDomain, "ccp", false, null));
|
||||
|
||||
when(accountService.getActiveAccountByName(username, domainId)).thenReturn(null);
|
||||
UserAccountVO userAccount = new UserAccountVO();
|
||||
userAccount.setAccountId(24);
|
||||
when(accountService.createUserAccount(eq(username), eq(""), eq("Admin"), eq("Admin"), eq("admin@ccp.citrix.com"), isNull(String.class),
|
||||
eq(username), eq(Account.ACCOUNT_TYPE_DOMAIN_ADMIN), eq(RoleType.DomainAdmin.getId()), eq(domainId), isNull(String.class),
|
||||
(java.util.Map<String,String>)isNull(), anyString(), anyString(), eq(User.Source.LDAP))).thenReturn(userAccount);
|
||||
|
||||
linkAccountToLdapCmd.execute();
|
||||
LinkAccountToLdapResponse result = (LinkAccountToLdapResponse)linkAccountToLdapCmd.getResponseObject();
|
||||
assertEquals("objectName", linkAccountToLdapCmd.APINAME, result.getObjectName());
|
||||
assertEquals("commandName", linkAccountToLdapCmd.getCommandName(), result.getResponseName());
|
||||
assertEquals("domainId", String.valueOf(domainId), result.getDomainId());
|
||||
assertEquals("type", type, result.getType());
|
||||
assertEquals("name", ldapDomain, result.getLdapDomain());
|
||||
assertEquals("accountId", String.valueOf(accountId), result.getAdminId());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
// 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.cloudstack.api.command;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccountVO;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.response.LinkDomainToLdapResponse;
|
||||
import org.apache.cloudstack.ldap.LdapManager;
|
||||
import org.apache.cloudstack.ldap.LdapUser;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isNull;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LinkDomainToLdapCmdTest implements LdapConfigurationChanger
|
||||
{
|
||||
@Mock
|
||||
LdapManager ldapManager;
|
||||
@Mock
|
||||
AccountService accountService;
|
||||
|
||||
LinkDomainToLdapCmd linkDomainToLdapCmd;
|
||||
|
||||
@Before
|
||||
public void setUp() throws NoSuchFieldException, IllegalAccessException {
|
||||
linkDomainToLdapCmd = new LinkDomainToLdapCmd();
|
||||
setHiddenField(linkDomainToLdapCmd, "_ldapManager", ldapManager);
|
||||
setHiddenField(linkDomainToLdapCmd, "_accountService", accountService);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void execute() throws Exception {
|
||||
// test with valid params and with admin who doesnt exist in cloudstack
|
||||
Long domainId = 1L;
|
||||
String type = "GROUP";
|
||||
String ldapDomain = "CN=test,DC=ccp,DC=Citrix,DC=com";
|
||||
short accountType = Account.ACCOUNT_TYPE_DOMAIN_ADMIN;
|
||||
String username = "admin";
|
||||
long accountId = 24;
|
||||
setHiddenField(linkDomainToLdapCmd, "ldapDomain", ldapDomain);
|
||||
setHiddenField(linkDomainToLdapCmd, "admin", username);
|
||||
setHiddenField(linkDomainToLdapCmd, "type", type);
|
||||
setHiddenField(linkDomainToLdapCmd, "domainId", domainId);
|
||||
setHiddenField(linkDomainToLdapCmd, "accountType", accountType);
|
||||
|
||||
LinkDomainToLdapResponse response = new LinkDomainToLdapResponse(domainId.toString(), type, ldapDomain, (short)accountType);
|
||||
when(ldapManager.linkDomainToLdap(linkDomainToLdapCmd)).thenReturn(response);
|
||||
when(ldapManager.getUser(username, type, ldapDomain, 1L)).thenReturn(new LdapUser(username, "admin@ccp.citrix.com", "Admin", "Admin", ldapDomain, "ccp", false, null));
|
||||
|
||||
when(accountService.getActiveAccountByName(username, domainId)).thenReturn(null);
|
||||
UserAccountVO userAccount = new UserAccountVO();
|
||||
userAccount.setAccountId(24);
|
||||
when(accountService.createUserAccount(eq(username), eq(""), eq("Admin"), eq("Admin"), eq("admin@ccp.citrix.com"), isNull(String.class),
|
||||
eq(username), eq(Account.ACCOUNT_TYPE_DOMAIN_ADMIN), eq(RoleType.DomainAdmin.getId()), eq(domainId), isNull(String.class),
|
||||
(java.util.Map<String,String>)isNull(), anyString(), anyString(), eq(User.Source.LDAP))).thenReturn(userAccount);
|
||||
|
||||
|
||||
linkDomainToLdapCmd.execute();
|
||||
LinkDomainToLdapResponse result = (LinkDomainToLdapResponse)linkDomainToLdapCmd.getResponseObject();
|
||||
assertEquals("objectName", "LinkDomainToLdap", result.getObjectName());
|
||||
assertEquals("commandName", linkDomainToLdapCmd.getCommandName(), result.getResponseName());
|
||||
assertEquals("domainId", domainId.toString(), result.getDomainId());
|
||||
assertEquals("type", type, result.getType());
|
||||
assertEquals("name", ldapDomain, result.getLdapDomain());
|
||||
assertEquals("accountId", String.valueOf(accountId), result.getAdminId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
// 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.cloudstack.ldap;
|
||||
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDao;
|
||||
import org.apache.cloudstack.ldap.dao.LdapConfigurationDaoImpl;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LdapConfigurationTest {
|
||||
|
||||
LdapConfigurationDao ldapConfigurationDao;
|
||||
LdapConfiguration ldapConfiguration;
|
||||
|
||||
private void overrideConfigValue(final String configKeyName, final Object o) throws IllegalAccessException, NoSuchFieldException {
|
||||
Field configKey = LdapConfiguration.class.getDeclaredField(configKeyName);
|
||||
configKey.setAccessible(true);
|
||||
|
||||
ConfigKey key = (ConfigKey)configKey.get(ldapConfiguration);
|
||||
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(configKey, configKey.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
Field f = ConfigKey.class.getDeclaredField("_value");
|
||||
f.setAccessible(true);
|
||||
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
|
||||
f.set(key, o);
|
||||
|
||||
Field dynamic = ConfigKey.class.getDeclaredField("_isDynamic");
|
||||
dynamic.setAccessible(true);
|
||||
modifiersField.setInt(dynamic, dynamic.getModifiers() & ~Modifier.FINAL);
|
||||
dynamic.setBoolean(key, false);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
ldapConfigurationDao = new LdapConfigurationDaoImpl();
|
||||
ldapConfiguration = new LdapConfiguration(ldapConfigurationDao);;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAuthenticationReturnsSimple() throws Exception {
|
||||
overrideConfigValue("ldapBindPrincipal", "cn=bla");
|
||||
overrideConfigValue("ldapBindPassword", "pw");
|
||||
String authentication = ldapConfiguration.getAuthentication(null);
|
||||
assertEquals("authentication should be set to simple", "simple", authentication);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getBaseDnReturnsABaseDn() throws Exception {
|
||||
overrideConfigValue("ldapBaseDn", "dc=cloudstack,dc=org");
|
||||
String baseDn = ldapConfiguration.getBaseDn(null);
|
||||
assertEquals("The set baseDn should be returned","dc=cloudstack,dc=org", baseDn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGroupUniqueMemberAttribute() throws Exception {
|
||||
String [] groupNames = {"bla", "uniquemember", "memberuid", "", null};
|
||||
for (String groupObject: groupNames) {
|
||||
overrideConfigValue("ldapGroupUniqueMemberAttribute", groupObject);
|
||||
String expectedResult = null;
|
||||
if(groupObject == null) {
|
||||
expectedResult = "uniquemember";
|
||||
} else {
|
||||
expectedResult = groupObject;
|
||||
};
|
||||
String result = ldapConfiguration.getGroupUniqueMemberAttribute(null);
|
||||
assertEquals("testing for " + groupObject, expectedResult, result);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSSLStatusCanBeTrue() throws Exception {
|
||||
// given: "We have a ConfigDao with values for truststore and truststore password set"
|
||||
overrideConfigValue("ldapTrustStore", "/tmp/ldap.ts");
|
||||
overrideConfigValue("ldapTrustStorePassword", "password");
|
||||
|
||||
assertTrue("A request is made to get the status of SSL should result in true", ldapConfiguration.getSSLStatus());
|
||||
}
|
||||
@Test
|
||||
public void getSearchGroupPrincipleReturnsSuccessfully() throws Exception {
|
||||
// We have a ConfigDao with a value for ldap.search.group.principle and an LdapConfiguration
|
||||
overrideConfigValue("ldapSearchGroupPrinciple", "cn=cloudstack,cn=users,dc=cloudstack,dc=org");
|
||||
String result = ldapConfiguration.getSearchGroupPrinciple(null);
|
||||
|
||||
assertEquals("The result holds the same value configDao did", "cn=cloudstack,cn=users,dc=cloudstack,dc=org",result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getTrustStorePasswordResopnds() throws Exception {
|
||||
// We have a ConfigDao with a value for truststore password
|
||||
overrideConfigValue("ldapTrustStorePassword", "password");
|
||||
|
||||
String result = ldapConfiguration.getTrustStorePassword();
|
||||
|
||||
assertEquals("The result is password", "password", result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getGroupObject() throws Exception {
|
||||
String [] groupNames = {"bla", "groupOfUniqueNames", "groupOfNames", "", null};
|
||||
for (String groupObject: groupNames) {
|
||||
overrideConfigValue("ldapGroupObject", groupObject);
|
||||
String expectedResult = null;
|
||||
if(groupObject == null) {
|
||||
expectedResult = "groupOfUniqueNames";
|
||||
} else {
|
||||
expectedResult = groupObject;
|
||||
};
|
||||
String result = ldapConfiguration.getGroupObject(null);
|
||||
assertEquals("testing for " + groupObject, expectedResult, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,10 @@ import com.cloud.template.TemplateManager;
|
|||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||
|
||||
/**
|
||||
* @deprecated use the more dynamic ConfigKey
|
||||
*/
|
||||
@Deprecated
|
||||
public enum Config {
|
||||
|
||||
// Alert
|
||||
|
|
@ -1814,42 +1818,6 @@ public enum Config {
|
|||
+ "If it is set to -1, then it means always use single-part upload to upload object to S3. ",
|
||||
null),
|
||||
|
||||
// Ldap
|
||||
LdapBasedn("Advanced", ManagementServer.class, String.class, "ldap.basedn", null, "Sets the basedn for LDAP", null),
|
||||
LdapBindPassword("Advanced", ManagementServer.class, String.class, "ldap.bind.password", null, "Sets the bind password for LDAP", null),
|
||||
LdapBindPrincipal("Advanced", ManagementServer.class, String.class, "ldap.bind.principal", null, "Sets the bind principal for LDAP", null),
|
||||
LdapEmailAttribute("Advanced", ManagementServer.class, String.class, "ldap.email.attribute", "mail", "Sets the email attribute used within LDAP", null),
|
||||
LdapFirstnameAttribute(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
String.class,
|
||||
"ldap.firstname.attribute",
|
||||
"givenname",
|
||||
"Sets the firstname attribute used within LDAP",
|
||||
null),
|
||||
LdapLastnameAttribute("Advanced", ManagementServer.class, String.class, "ldap.lastname.attribute", "sn", "Sets the lastname attribute used within LDAP", null),
|
||||
LdapUsernameAttribute("Advanced", ManagementServer.class, String.class, "ldap.username.attribute", "uid", "Sets the username attribute used within LDAP", null),
|
||||
LdapUserObject("Advanced", ManagementServer.class, String.class, "ldap.user.object", "inetOrgPerson", "Sets the object type of users within LDAP", null),
|
||||
LdapSearchGroupPrinciple(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
String.class,
|
||||
"ldap.search.group.principle",
|
||||
null,
|
||||
"Sets the principle of the group that users must be a member of",
|
||||
null),
|
||||
LdapTrustStore("Advanced", ManagementServer.class, String.class, "ldap.truststore", null, "Sets the path to the truststore to use for SSL", null),
|
||||
LdapTrustStorePassword("Advanced", ManagementServer.class, String.class, "ldap.truststore.password", null, "Sets the password for the truststore", null),
|
||||
LdapGroupObject("Advanced", ManagementServer.class, String.class, "ldap.group.object", "groupOfUniqueNames", "Sets the object type of groups within LDAP", null),
|
||||
LdapGroupUniqueMemberAttribute(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
String.class,
|
||||
"ldap.group.user.uniquemember",
|
||||
"uniquemember",
|
||||
"Sets the attribute for uniquemembers within a group",
|
||||
null),
|
||||
|
||||
// VMSnapshots
|
||||
VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null),
|
||||
VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null),
|
||||
|
|
@ -1979,17 +1947,6 @@ public enum Config {
|
|||
_scope = ConfigKey.Scope.Global.toString();
|
||||
}
|
||||
|
||||
private Config(String category, Class<?> componentClass, Class<?> type, String name, String defaultValue, String description, String range, String scope) {
|
||||
_category = category;
|
||||
_componentClass = componentClass;
|
||||
_type = type;
|
||||
_name = name;
|
||||
_defaultValue = defaultValue;
|
||||
_description = description;
|
||||
_range = range;
|
||||
_scope = scope;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return _category;
|
||||
}
|
||||
|
|
@ -2010,10 +1967,6 @@ public enum Config {
|
|||
return _type;
|
||||
}
|
||||
|
||||
public Class<?> getComponentClass() {
|
||||
return _componentClass;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return _scope;
|
||||
}
|
||||
|
|
@ -2081,8 +2034,4 @@ public enum Config {
|
|||
}
|
||||
return categories;
|
||||
}
|
||||
|
||||
public static List<Config> getConfigListByScope(String scope) {
|
||||
return s_scopeLevelConfigsMap.get(scope);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,8 +131,10 @@ import com.cloud.dc.dao.VlanDao;
|
|||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentClusterPlanner;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.domain.DomainDetailVO;
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.event.ActionEvent;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.event.UsageEventUtils;
|
||||
|
|
@ -327,6 +329,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
@Inject
|
||||
AccountDetailsDao _accountDetailsDao;
|
||||
@Inject
|
||||
DomainDetailsDao _domainDetailsDao;
|
||||
@Inject
|
||||
PrimaryDataStoreDao _storagePoolDao;
|
||||
@Inject
|
||||
NicSecondaryIpDao _nicSecondaryIpDao;
|
||||
|
|
@ -548,6 +552,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
_imageStoreDetailsDao.addDetail(resourceId, name, value, true);
|
||||
break;
|
||||
|
||||
case Domain:
|
||||
final DomainVO domain = _domainDao.findById(resourceId);
|
||||
if (domain == null) {
|
||||
throw new InvalidParameterValueException("unable to find domain by id " + resourceId);
|
||||
}
|
||||
DomainDetailVO domainDetailVO = _domainDetailsDao.findDetail(resourceId, name);
|
||||
if (domainDetailVO == null) {
|
||||
domainDetailVO = new DomainDetailVO(resourceId, name, value);
|
||||
_domainDetailsDao.persist(domainDetailVO);
|
||||
} else {
|
||||
domainDetailVO.setValue(value);
|
||||
_domainDetailsDao.update(domainDetailVO.getId(), domainDetailVO);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidParameterValueException("Scope provided is invalid");
|
||||
}
|
||||
|
|
@ -655,6 +674,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
final Long storagepoolId = cmd.getStoragepoolId();
|
||||
final Long accountId = cmd.getAccountId();
|
||||
final Long imageStoreId = cmd.getImageStoreId();
|
||||
final Long domainId = cmd.getDomainId();
|
||||
CallContext.current().setEventDetails(" Name: " + name + " New Value: " + (name.toLowerCase().contains("password") ? "*****" : value == null ? "" : value));
|
||||
// check if config value exists
|
||||
final ConfigurationVO config = _configDao.findByName(name);
|
||||
|
|
@ -700,6 +720,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
id = accountId;
|
||||
paramCountCheck++;
|
||||
}
|
||||
if (domainId != null) {
|
||||
scope = ConfigKey.Scope.Domain.toString();
|
||||
id = domainId;
|
||||
paramCountCheck++;
|
||||
}
|
||||
if (storagepoolId != null) {
|
||||
scope = ConfigKey.Scope.StoragePool.toString();
|
||||
id = storagepoolId;
|
||||
|
|
|
|||
|
|
@ -1686,6 +1686,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
final Long clusterId = cmd.getClusterId();
|
||||
final Long storagepoolId = cmd.getStoragepoolId();
|
||||
final Long accountId = cmd.getAccountId();
|
||||
final Long domainId = cmd.getDomainId();
|
||||
final Long imageStoreId = cmd.getImageStoreId();
|
||||
String scope = null;
|
||||
Long id = null;
|
||||
|
|
@ -1706,6 +1707,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
id = accountId;
|
||||
paramCountCheck++;
|
||||
}
|
||||
if (domainId != null) {
|
||||
scope = ConfigKey.Scope.Domain.toString();
|
||||
id = domainId;
|
||||
paramCountCheck++;
|
||||
}
|
||||
if (storagepoolId != null) {
|
||||
scope = ConfigKey.Scope.StoragePool.toString();
|
||||
id = storagepoolId;
|
||||
|
|
|
|||
|
|
@ -215,4 +215,6 @@ public interface AccountManager extends AccountService, Configurable{
|
|||
"false",
|
||||
"This parameter allows the users to enable or disable of showing secret key as a part of response for various APIs. By default it is set to false.",
|
||||
true);
|
||||
|
||||
boolean moveUser(long id, Long domainId, long accountId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1702,17 +1702,32 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
|
||||
public boolean moveUser(MoveUserCmd cmd) {
|
||||
UserVO user = getValidUserVO(cmd.getId());
|
||||
final Long id = cmd.getId();
|
||||
UserVO user = getValidUserVO(id);
|
||||
Account oldAccount = _accountDao.findById(user.getAccountId());
|
||||
checkAccountAndAccess(user, oldAccount);
|
||||
long domainId = oldAccount.getDomainId();
|
||||
|
||||
long newAccountId = getNewAccountId(cmd, domainId);
|
||||
long newAccountId = getNewAccountId(domainId, cmd.getAccountName(), cmd.getAccountId());
|
||||
|
||||
return moveUser(user, newAccountId);
|
||||
}
|
||||
|
||||
public boolean moveUser(long id, Long domainId, long accountId) {
|
||||
UserVO user = getValidUserVO(id);
|
||||
Account oldAccount = _accountDao.findById(user.getAccountId());
|
||||
checkAccountAndAccess(user, oldAccount);
|
||||
Account newAccount = _accountDao.findById(accountId);
|
||||
checkIfNotMovingAcrossDomains(domainId, newAccount);
|
||||
return moveUser(user , accountId);
|
||||
}
|
||||
|
||||
private boolean moveUser(UserVO user, long newAccountId) {
|
||||
if(newAccountId == user.getAccountId()) {
|
||||
// could do a not silent fail but the objective of the user is reached
|
||||
return true; // no need to create a new user object for this user
|
||||
}
|
||||
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
|
|
@ -1721,34 +1736,37 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
user.setUuid(UUID.randomUUID().toString());
|
||||
_userDao.update(user.getId(),user);
|
||||
newUser.setAccountId(newAccountId);
|
||||
boolean success = _userDao.remove(cmd.getId());
|
||||
boolean success = _userDao.remove(user.getId());
|
||||
UserVO persisted = _userDao.persist(newUser);
|
||||
return success && persisted.getUuid().equals(user.getExternalEntity());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private long getNewAccountId(MoveUserCmd cmd, long domainId) {
|
||||
private long getNewAccountId(long domainId, String accountName, Long accountId) {
|
||||
Account newAccount = null;
|
||||
if (StringUtils.isNotBlank(cmd.getAccountName())) {
|
||||
if (StringUtils.isNotBlank(accountName)) {
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Getting id for account by name '" + cmd.getAccountName() + "' in domain " + domainId);
|
||||
s_logger.debug("Getting id for account by name '" + accountName + "' in domain " + domainId);
|
||||
}
|
||||
newAccount = _accountDao.findEnabledAccount(cmd.getAccountName(), domainId);
|
||||
newAccount = _accountDao.findEnabledAccount(accountName, domainId);
|
||||
}
|
||||
if (newAccount == null && cmd.getAccountId() != null) {
|
||||
newAccount = _accountDao.findById(cmd.getAccountId());
|
||||
if (newAccount == null && accountId != null) {
|
||||
newAccount = _accountDao.findById(accountId);
|
||||
}
|
||||
if (newAccount == null) {
|
||||
throw new CloudRuntimeException("no account name or account id. this should have been caught before this point");
|
||||
}
|
||||
long newAccountId = newAccount.getAccountId();
|
||||
|
||||
checkIfNotMovingAcrossDomains(domainId, newAccount);
|
||||
return newAccount.getAccountId();
|
||||
}
|
||||
|
||||
private void checkIfNotMovingAcrossDomains(long domainId, Account newAccount) {
|
||||
if(newAccount.getDomainId() != domainId) {
|
||||
// not in scope
|
||||
throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
|
||||
}
|
||||
return newAccountId;
|
||||
}
|
||||
|
||||
private void checkAccountAndAccess(UserVO user, Account account) {
|
||||
|
|
|
|||
|
|
@ -123,7 +123,13 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
@Override
|
||||
public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveUser(long id, Long domainId, long accountId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,34 +19,6 @@ package org.apache.cloudstack.networkoffering;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.cloud.network.dao.FirewallRulesDcidrsDaoImpl;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.region.PortableIpDaoImpl;
|
||||
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
|
||||
import org.apache.cloudstack.region.dao.RegionDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.api.query.dao.UserAccountJoinDaoImpl;
|
||||
|
|
@ -67,6 +39,7 @@ import com.cloud.dc.dao.PodVlanDaoImpl;
|
|||
import com.cloud.dc.dao.PodVlanMapDaoImpl;
|
||||
import com.cloud.dc.dao.VlanDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDetailsDao;
|
||||
import com.cloud.event.dao.UsageEventDaoImpl;
|
||||
import com.cloud.host.dao.HostDaoImpl;
|
||||
import com.cloud.host.dao.HostDetailsDaoImpl;
|
||||
|
|
@ -79,6 +52,7 @@ import com.cloud.network.StorageNetworkManager;
|
|||
import com.cloud.network.dao.AccountGuestVlanMapDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesDaoImpl;
|
||||
import com.cloud.network.dao.FirewallRulesDcidrsDaoImpl;
|
||||
import com.cloud.network.dao.IPAddressDaoImpl;
|
||||
import com.cloud.network.dao.LoadBalancerDaoImpl;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
|
|
@ -107,6 +81,7 @@ import com.cloud.server.ConfigurationServer;
|
|||
import com.cloud.server.ManagementService;
|
||||
import com.cloud.service.dao.ServiceOfferingDaoImpl;
|
||||
import com.cloud.service.dao.ServiceOfferingDetailsDaoImpl;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.dao.DiskOfferingDaoImpl;
|
||||
import com.cloud.storage.dao.SnapshotDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
|
||||
|
|
@ -123,6 +98,30 @@ import com.cloud.vm.dao.NicDaoImpl;
|
|||
import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDaoImpl;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.region.PortableIpDaoImpl;
|
||||
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
|
||||
import org.apache.cloudstack.region.dao.RegionDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDaoImpl;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
|
||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = {AccountVlanMapDaoImpl.class, DomainVlanMapDaoImpl.class, VolumeDaoImpl.class, HostPodDaoImpl.class, DomainDaoImpl.class, ServiceOfferingDaoImpl.class,
|
||||
|
|
@ -320,6 +319,11 @@ public class
|
|||
return Mockito.mock(AccountDetailsDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DomainDetailsDao domainDetailsDao() {
|
||||
return Mockito.mock(DomainDetailsDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DataStoreManager dataStoreManager() {
|
||||
return Mockito.mock(DataStoreManager.class);
|
||||
|
|
|
|||
|
|
@ -457,6 +457,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
tabFilter: function(args) {
|
||||
var hiddenTabs = [];
|
||||
if(!isAdmin()) {
|
||||
hiddenTabs.push('settings');
|
||||
}
|
||||
return hiddenTabs;
|
||||
},
|
||||
|
||||
tabs: {
|
||||
details: {
|
||||
title: 'label.details',
|
||||
|
|
@ -638,36 +647,6 @@
|
|||
domainObj["vmTotal"] = totalVMs;
|
||||
domainObj["volumeTotal"] = totalVolumes;
|
||||
|
||||
/* $.ajax({
|
||||
url: createURL("listVirtualMachines&details=min&domainid=" + domainObj.id),
|
||||
async: false,
|
||||
dataType: "json",
|
||||
success: function(json) {
|
||||
var items = json.listvirtualmachinesresponse.virtualmachine;
|
||||
var total;
|
||||
if (items != null)
|
||||
total = items.length;
|
||||
else
|
||||
total = 0;
|
||||
domainObj["vmTotal"] = total;
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listVolumes&domainid=" + domainObj.id),
|
||||
async: false,
|
||||
dataType: "json",
|
||||
success: function(json) {
|
||||
var items = json.listvolumesresponse.volume;
|
||||
var total;
|
||||
if (items != null)
|
||||
total = items.length;
|
||||
else
|
||||
total = 0;
|
||||
domainObj["volumeTotal"] = total;
|
||||
}
|
||||
});*/
|
||||
|
||||
$.ajax({
|
||||
url: createURL("listResourceLimits&domainid=" + domainObj.id),
|
||||
async: false,
|
||||
|
|
@ -722,7 +701,58 @@
|
|||
actionFilter: domainActionfilter
|
||||
});
|
||||
}
|
||||
},
|
||||
// Granular settings for domains
|
||||
settings: {
|
||||
title: 'label.settings',
|
||||
custom: cloudStack.uiCustom.granularSettings({
|
||||
dataProvider: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('listConfigurations&domainid=' + args.context.domains[0].id),
|
||||
data: listViewDataProvider(args, {}, { searchBy: 'name' }),
|
||||
success: function(json) {
|
||||
args.response.success({
|
||||
data: json.listconfigurationsresponse.configuration
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
actions: {
|
||||
edit: function(args) {
|
||||
// call updateDomainLevelParameters
|
||||
var data = {
|
||||
name: args.data.jsonObj.name,
|
||||
value: args.data.value
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: createURL('updateConfiguration&domainid=' + args.context.domains[0].id),
|
||||
data: data,
|
||||
success: function(json) {
|
||||
var item = json.updateconfigurationresponse.configuration;
|
||||
args.response.success({
|
||||
data: item
|
||||
});
|
||||
},
|
||||
|
||||
error: function(json) {
|
||||
args.response.error(parseXMLHttpResponse(json));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
labelField: 'name',
|
||||
|
|
|
|||
Loading…
Reference in New Issue