Author: Chad Sikorra (Chad.Sikorra@gmail.com)
Inheritance: implements LdapTools\Cache\CacheableItemInterface
 function it_should_get_an_operator_filter_for_a_schema_adding_the_objectClass_objectCategory_and_filter_array()
 {
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setObjectClass(['user']);
     $schema->setObjectCategory('person');
     $this->getOperatorForSchema($schema, [])->toLdapFilter()->shouldBeEqualTo('(&(objectCategory=person)(objectClass=user))');
     $this->getOperatorForSchema($schema, ['starts_with' => ['username', 'admin']])->toLdapFilter()->shouldBeEqualTo('(&(&(objectCategory=person)(objectClass=user))(&(username=admin*)))');
 }
 function it_should_return_all_LDAP_attributes_merged_with_the_schema_if_a_wildcard_was_used()
 {
     $map = ['firstName' => 'givenName', 'lastName' => 'sn', 'emailAddress' => 'mail', 'name' => 'cn'];
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setAttributeMap($map);
     $fromLdap = ['givenName' => 'Egon', 'sn' => 'Spengler', 'mail' => '*****@*****.**', 'cn' => 'Egon', 'dn' => 'CN=Egon,dc=whhhhhy,dc=local'];
     $keys = array_unique(array_merge(array_keys($fromLdap), array_keys($map)));
     $this->beConstructedWith($schema);
     $this->fromLdap($fromLdap, ['*'])->shouldHaveKeys($keys);
 }
 function let(LdapConnectionInterface $connection, AddOperation $operation)
 {
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setAttributeMap(['username' => 'sAMAccountName', 'emailAddress' => 'mail', 'disabled' => 'userAccountControl', 'passwordMustChange' => 'pwdLastSet', 'passwordNeverExpires' => 'userAccountControl', 'trustedForAllDelegation' => 'userAccountControl', 'groups' => 'memberOf']);
     $schema->setConverterMap(['disabled' => 'user_account_control', 'passwordMustChange' => 'password_must_change', 'trustedForAllDelegation' => 'user_account_control', 'passwordNeverExpires' => 'user_account_control', 'groups' => 'group_membership']);
     $schema->setConverterOptions(['user_account_control' => ['uacMap' => ['disabled' => '2', 'passwordNeverExpires' => '65536', 'smartCardRequired' => '262144', 'trustedForAllDelegation' => '524288', 'passwordIsReversible' => '128'], 'defaultValue' => '512'], 'group_membership' => ['groups' => ['to_attribute' => 'member', 'from_attribute' => 'memberOf', 'attribute' => 'sAMAccountName', 'filter' => ['objectClass' => 'group']]]]);
     $this->schema = $schema;
     $connection->getConfig()->willReturn(new DomainConfiguration('foo.bar'));
     $this->beConstructedThrough('getInstance', [$schema, $this->entryTo, AttributeConverterInterface::TYPE_CREATE]);
 }
 function let(LdapConnectionInterface $connection)
 {
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setAttributeMap(['username' => 'sAMAccountName', 'emailAddress' => 'mail', 'disabled' => 'userAccountControl', 'passwordMustChange' => 'pwdLastSet', 'passwordNeverExpires' => 'userAccountControl', 'trustedForAllDelegation' => 'userAccountControl', 'groups' => 'memberOf']);
     $schema->setConverterMap(['disabled' => 'user_account_control', 'passwordMustChange' => 'password_must_change', 'trustedForAllDelegation' => 'user_account_control', 'passwordNeverExpires' => 'user_account_control', 'groups' => 'group_membership']);
     $schema->setConverterOptions(['user_account_control' => ['uacMap' => ['disabled' => '2', 'passwordNeverExpires' => '65536', 'smartCardRequired' => '262144', 'trustedForAllDelegation' => '524288', 'passwordIsReversible' => '128'], 'defaultValue' => '512'], 'group_membership' => ['groups' => ['to_attribute' => 'member', 'from_attribute' => 'memberOf', 'attribute' => 'sAMAccountName', 'filter' => ['objectClass' => 'group']]]]);
     $this->expectedSearch = new QueryOperation('(&(distinguishedName=cn=foo,dc=foo,dc=bar))', ['userAccountControl']);
     $this->schema = $schema;
     $connection->getConfig()->willReturn(new DomainConfiguration('foo.bar'));
     $connection->getRootDse()->willReturn(new LdapObject(['foo' => 'bar']));
 }
Esempio n. 5
0
 /**
  * Determine what attributes should be selected. This helps account for all attributes being selected both within
  * and out of the context of a schema.
  *
  * @param array $attributes
  * @param LdapObjectSchema|null $schema
  * @return array
  */
 protected function getSelectedQueryAttributes(array $attributes, LdapObjectSchema $schema = null)
 {
     // Interpret a single wildcard as only schema attributes.
     if ($schema && !empty($attributes) && $attributes[0] == '*') {
         $attributes = array_keys($schema->getAttributeMap());
         // Interpret a double wildcard as all LDAP attributes even if they aren't in the schema file.
     } elseif ($schema && !empty($attributes) && $attributes[0] == '**') {
         $attributes = ['*'];
     }
     return $attributes;
 }
Esempio n. 6
0
 /**
  * Add a LdapObjectSchema for a object type that will be selected for. Optionally specify a specific alias that is
  * used to reference it. If no alias is specified, then it uses the object type name for the schema.
  *
  * @param LdapObjectSchema $schema
  * @param null|string $alias
  */
 public function addLdapObjectSchema(LdapObjectSchema $schema, $alias = null)
 {
     if (!is_null($alias) && !is_string($alias)) {
         throw new InvalidArgumentException(sprintf('The alias for type "%s" must be a string, but "%s" was given.', $schema->getObjectType(), is_string($alias) ? $alias : gettype($alias)));
     }
     $alias = $alias ?: $schema->getObjectType();
     if (!preg_match(self::ALIAS_REGEX, $alias)) {
         throw new InvalidArgumentException(sprintf('The alias "%s" for type "%s" is invalid. Allowed characters are: A-Z, a-z, 0-9, -, _', $alias, $schema->getObjectType()));
     }
     $this->aliases[$alias] = $schema;
 }
 function it_should_hydrate_a_ldap_object_with_batch_modification()
 {
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setAttributeMap(['firstName' => 'givenName', 'lastName' => 'sn', 'emailAddress' => 'mail', 'username' => 'sAMAccountName']);
     $this->setLdapObjectSchema($schema);
     $ldapObject = new LdapObject(['dn' => 'cn=foo,dc=foo,dc=bar'], [], 'user', 'user');
     $ldapObject->set('firstName', 'Chad');
     $ldapObject->add('lastName', 'Sikorra');
     $ldapObject->remove('username', 'csikorra');
     $ldapObject->reset('emailAddress');
     $this->hydrateToLdap($ldapObject)->shouldBeEqualTo($this->batch);
     $this->hydrateToLdap($ldapObject)->shouldHaveCount(4);
 }
 function it_should_set_the_scope_based_off_the_schema($connection)
 {
     $operation = new QueryOperation('(foo=bar)');
     $this->setLdapObjectSchema($this->schema);
     $this->setLdapConnection($connection);
     $this->hydrateToLdap($operation)->getScope()->shouldBeEqualTo('subtree');
     $this->schema->setScope(QueryOperation::SCOPE['ONELEVEL']);
     $this->hydrateToLdap($operation)->getScope()->shouldBeEqualTo('onelevel');
 }
 /**
  * Determine what attributes should be selected. This accounts for a query wanting all attributes.
  *
  * @param array $selected
  * @param array $entry
  * @return array
  */
 protected function getSelectedAttributes(array $selected, array $entry)
 {
     if (count($selected) === 1 && $selected[0] == '*' && !$this->schema) {
         $selected = array_keys($entry);
     } elseif (count($selected) === 1 && $selected[0] == '*' && $this->schema) {
         $selected = array_unique(array_merge(array_keys($this->schema->getAttributeMap()), array_keys($entry)));
     }
     return $selected;
 }
Esempio n. 10
0
 /**
  * Determines which method to actually call.
  *
  * @param string $method
  * @param mixed $arguments
  * @return mixed
  */
 public function __call($method, $arguments)
 {
     if (!preg_match('/^(findOneBy|findBy)(.*)$/', $method, $matches)) {
         throw new \RuntimeException(sprintf('The method name should begin with "findOneBy" or "findBy". "%s" is unknown.', $method));
     }
     if (empty($arguments)) {
         throw new \RuntimeException(sprintf('The method name should begin with "findOneBy" or "findBy". "%s" is unknown.', $method));
     }
     $method = $matches[1];
     $attribute = lcfirst($matches[2]);
     if (!$this->schema->hasAttribute($attribute)) {
         throw new \RuntimeException(sprintf('To call "%s" you must define the attribute "%s" in your schema.', $method, $attribute));
     }
     if (1 == count($arguments)) {
         return $this->{$method}([$attribute => $arguments[0]]);
     } else {
         return $this->{$method}(array_merge([$attribute => array_shift($arguments)], $arguments));
     }
 }
 /**
  * Whether or not the item needs to be parsed and cached.
  *
  * @param string $schemaName
  * @param string $cacheItem
  * @return bool
  */
 protected function shouldBuildCacheItem($schemaName, $cacheItem)
 {
     $cacheOutOfDate = false;
     if ($this->cache->getUseAutoCache()) {
         $lastModTime = $this->parser->getSchemaModificationTime($schemaName);
         $cacheCreationTime = $this->cache->getCacheCreationTime(LdapObjectSchema::getCacheType(), $cacheItem);
         $cacheOutOfDate = !$lastModTime || $lastModTime > $cacheCreationTime;
     }
     return $cacheOutOfDate || !$this->cache->contains(LdapObjectSchema::getCacheType(), $cacheItem);
 }
Esempio n. 12
0
 /**
  * @param array $filter
  * @param BaseOperator|null $operator
  * @return BaseOperator
  */
 protected function getOperatorForArray(array $filter, BaseOperator $operator = null)
 {
     $filter = !empty($filter) ? $this->filterBuilder->bAnd(...$this->parseFilterToOperators($filter)) : null;
     if (!$filter && !$operator) {
         throw new InvalidArgumentException(sprintf('Type "%s" for schema "%s" needs to have one of the following defined: objectClass, objectCategory, or filter.', $this->schema->getObjectType(), $this->schema->getSchemaName()));
     } elseif ($filter && $operator) {
         $operator = $this->filterBuilder->bAnd($operator, $filter);
     } else {
         $operator = $operator ?: $filter;
     }
     return $operator;
 }
Esempio n. 13
0
 /**
  * Convert a set of values for an attribute.
  *
  * @param string $attribute
  * @param array $values
  * @param string $direction
  * @param AttributeConverterInterface|null $converter
  * @return mixed
  */
 protected function doConvertValues($attribute, array $values, $direction, AttributeConverterInterface $converter = null)
 {
     $converter = is_null($converter) ? $this->getConverterWithOptions($this->schema->getConverter($attribute)) : $converter;
     $converter->setAttribute($attribute);
     if ($converter->getIsMultiValuedConverter()) {
         $values = $converter->{$direction}($values);
     } else {
         foreach ($values as $index => $value) {
             $values[$index] = $converter->{$direction}($value);
         }
     }
     return $values;
 }
Esempio n. 14
0
 /**
  * Checks to make sure all required attributes are present.
  *
  * @param array $attributes
  */
 protected function validateAttributesToLdap(array $attributes)
 {
     if (!$this->schema) {
         return;
     }
     $missing = [];
     foreach ($this->schema->getRequiredAttributes() as $attribute) {
         if (!array_key_exists(MBString::strtolower($attribute), MBString::array_change_key_case($attributes))) {
             $missing[] = $attribute;
         }
     }
     if (!empty($missing)) {
         throw new LogicException(sprintf('The following required attributes are missing: %s', implode(', ', $missing)));
     }
 }
Esempio n. 15
0
 function it_should_pass_operation_options_on_to_the_LdapQuery_class_correctly()
 {
     $this->objectSchema->setAttributesToSelect(['foo', 'bar']);
     $this->select();
     $this->from($this->objectSchema);
     $this->setScopeOneLevel();
     $this->setBaseDn('ou=stuff,dc=foo,dc=bar');
     $this->setPageSize('9001');
     $this->getLdapQuery()->getQueryOperation()->getAttributes()->shouldBeEqualTo([]);
     $this->getLdapQuery()->getQueryOperation()->getBaseDn()->shouldBeEqualTo('ou=stuff,dc=foo,dc=bar');
     $this->getLdapQuery()->getQueryOperation()->getScope()->shouldBeEqualTo(QueryOperation::SCOPE['ONELEVEL']);
     $this->getLdapQuery()->getQueryOperation()->getPageSize()->shouldBeEqualTo('9001');
     $this->getLdapQuery()->getQueryOperation()->getFilter()->toLdapFilter()->shouldBeEqualTo('(&(objectCategory=person)(objectClass=user))');
     $this->select('foo');
     $this->getLdapQuery()->getQueryOperation()->getAttributes()->shouldBeEqualTo(['foo']);
 }
 function it_should_convert_the_filter_for_a_schema_if_it_uses_mapped_attribute_names_with_converters()
 {
     $this->schema->setFilter(new Comparison('exchangeHideFromGAL', '=', true));
     $this->toLdap()->toLdapFilter()->shouldEqual('(|(msExchHideFromAddressLists=TRUE)(objectClass=organizationalUnit))');
 }
Esempio n. 17
0
 function it_should_be_case_insensitive_when_looking_up_an_item_in_the_cache()
 {
     $this->setCacheFolder($this->testCacheDir);
     $item = new LdapObjectSchema('foo', 'bar');
     $this->set($item);
     $this->contains(LdapObjectSchema::getCacheType(), 'Foo.Bar')->shouldBeEqualTo(true);
     $this->get(LdapObjectSchema::getCacheType(), 'Foo.Bar')->shouldBeLike($item);
     $this->deleteAll();
 }
Esempio n. 18
0
 /**
  * Validate that an object schema meets the minimum requirements.
  *
  * @param LdapObjectSchema $schema
  * @throws SchemaParserException
  */
 protected function validateObjectSchema($schema)
 {
     if (empty($schema->getAttributeMap())) {
         throw new SchemaParserException(sprintf('Object type "%s" has no attributes defined.', $schema->getObjectType()));
     } elseif (!(bool) count(array_filter(array_keys($schema->getAttributeMap()), 'is_string'))) {
         throw new SchemaParserException('The attributes for a schema should be an associative array.');
     }
     if ($schema->getScope() && !in_array($schema->getScope(), QueryOperation::SCOPE)) {
         throw new SchemaParserException(sprintf('The scope "%s" is not valid. Valid types are: %s', $schema->getScope(), implode(', ', QueryOperation::SCOPE)));
     }
 }
Esempio n. 19
0
 public function it_should_always_return_null_when_calling_get()
 {
     $item = new LdapObjectSchema('foo', 'bar');
     $this->get($item->getCacheType(), $item->getSchemaName() . '.' . $item->getObjectType())->shouldBeNull();
 }
 function it_should_get_the_ldap_filter_for_a_specific_alias()
 {
     $foo = new LdapObjectSchema('foo', 'foo');
     $foo->setFilter(new Comparison('foo', Comparison::EQ, 'bar'));
     $bar = new LdapObjectSchema('foo', 'bar');
     $bar->setFilter(new Comparison('bar', Comparison::EQ, 'foo'));
     $this->addLdapObjectSchema($bar);
     $this->addLdapObjectSchema($foo);
     $this->toLdapFilter('foo')->shouldBeEqualTo('(foo=bar)');
     $this->toLdapFilter('bar')->shouldBeEqualTo('(bar=foo)');
 }
Esempio n. 21
0
 function it_should_convert_values_when_hydrating_to_ldap()
 {
     $schema = new LdapObjectSchema('ad', 'user');
     $schema->setAttributeMap(['foo' => 'bar']);
     $schema->setConverterMap(['foo' => 'bool']);
     $this->setLdapObjectSchema($schema);
     $attributes = $this->objectToLdap;
     $attributes['foo'] = true;
     $this->hydrateToLdap($attributes)->shouldContain('TRUE');
 }
Esempio n. 22
0
 function it_should_limit_the_results_for_subsequent_operations_if_a_size_limit_is_set_so_we_dont_go_over_the_limit($connection)
 {
     $foo = new LdapObjectSchema('foo', 'foo');
     $bar = new LdapObjectSchema('foo', 'bar');
     $foo->setFilter(new Comparison('foo', '=', 'bar'));
     $bar->setFilter(new Comparison('bar', '=', 'foo'));
     $filter = new OperatorCollection();
     $filter->addLdapObjectSchema($foo);
     $filter->addLdapObjectSchema($bar);
     $this->operation->setFilter($filter);
     $this->operation->setAttributes([]);
     $this->operation->setSizeLimit(4);
     $connection->execute(Argument::that(function ($op) {
         return $op->getFilter() == '(foo=bar)' && $op->getSizeLimit() == 4;
     }))->shouldBeCalled()->willReturn($this->ldapEntries);
     // The above returns 2 results, since the limit is 4 this next call should be set to a max of 2...
     $connection->execute(Argument::that(function ($op) {
         return $op->getFilter() == '(bar=foo)' && $op->getSizeLimit() == 2;
     }))->shouldBeCalled()->willReturn($this->sortEntries);
     $this->getResult();
 }
 function it_should_not_call_the_load_schema_event_when_retrieving_from_the_cache(CacheInterface $cache, SchemaParserInterface $parser, $dispatcher)
 {
     $cache->getUseAutoCache()->willReturn(true);
     $cache->contains(LdapObjectSchema::getCacheType(), 'ad.user')->willReturn(true);
     $cache->getCacheCreationTime(LdapObjectSchema::getCacheType(), 'ad.user')->willReturn(new \DateTime('2015-1-3'));
     $cache->set(Argument::any())->shouldNotBeCalled();
     $cache->get(LdapObjectSchema::getCacheType(), 'ad.user')->willReturn(new LdapObjectSchema('ad', 'user'));
     $parser->parse('ad', 'user')->shouldNotBeCalled();
     $parser->getSchemaModificationTime('ad')->willReturn(new \DateTime('2015-1-2'));
     new LdapObjectSchemaEvent(Event::LDAP_SCHEMA_LOAD, new LdapObjectSchema('ad', 'user'));
     $dispatcher->dispatch(Argument::type('\\LdapTools\\Event\\LdapObjectSchemaEvent'))->shouldNotBeCalled();
     $this->beConstructedWith($cache, $parser, $dispatcher);
     $this->get('ad', LdapObjectType::USER);
 }