Skip to content

Bring Branch up to date. #296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Nov 1, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
273972f
Merge pull request #275 from adobe-apiplatform/v2_doc_update
adobeDan Sep 20, 2017
42f7e54
Update connector-ldap.yml
Luci2015 Sep 26, 2017
770beab
Update connector-ldap.yml
Luci2015 Sep 27, 2017
448d03a
Merge pull request #280 from Luci2015/v2
adobeDan Sep 28, 2017
d971612
Update default.html
phil-levy Oct 11, 2017
59da5b4
Merge pull request #285 from adobe-apiplatform/phil-levy-patch-1
adobeDan Oct 11, 2017
a2a9ee7
fix #286: allow attribute management on Adobe IDs
adobeDan Oct 18, 2017
00ce232
escape special chars for strings that will be formatted into ldap que…
adorton-adobe Oct 25, 2017
1cbabf2
expand escape char list and get hex value for escape char replacement
adorton-adobe Oct 25, 2017
fc0ee12
revise the comments to reflect changes to character replacement logic
adorton-adobe Oct 25, 2017
49d9588
Readibility and comment clarity. Fixes #288
adorton-adobe Oct 26, 2017
473371e
Merge pull request #287 from adorton-adobe/feature/ldap-escape-string
adobeDan Oct 26, 2017
0461403
fix #283: don't import keyring unless needed.
adobeDan Oct 26, 2017
f368d29
Prepare for 2.2.2rc1 release.
adobeDan Oct 26, 2017
3cc4953
Merge pull request #289 from adobe-apiplatform/v2
adobeDan Oct 26, 2017
c8cdb6b
Fix #290: match pex requirements on wheel
adobeDan Oct 26, 2017
6b5048e
Cleanup of creation logic for Adobe users.
adobeDan Oct 29, 2017
01cacec
Update version and release notes for v2.2.2rc2
adobeDan Oct 30, 2017
de99442
Fix #294: keep statistics on user changes in secondaries.
adobeDan Oct 30, 2017
c3ca46a
Update release notes for v2.2.2rc2
adobeDan Oct 30, 2017
205b53f
Merge pull request #295 from adobe-apiplatform/v2
adobeDan Oct 30, 2017
845f594
(No Issue) Clean up detritus in the Makefile
adobeDan Oct 30, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ endif

pex:
pip install --upgrade pip
pip install --upgrade wheel requests pex
pip install --upgrade 'wheel<0.30.0' requests pex
-$(RM) $(output_dir)
pex -v -o $(output_dir)/$(output_filename)$(output_file_extension) -m user_sync.app \
-f $(prebuilt_dir) \
--disable-cache \
--not-zip-safe .
-$(RM) wheelhouse

test:
nosetests --no-byte-compile tests
29 changes: 13 additions & 16 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,31 @@
# Release Notes for User Sync Tool Version 2.2.1
# Release Notes for User Sync Tool Version 2.2.2

These notes apply to v2.2.1 of 2017-08-30.
These notes apply to v2.2.2rc2 of 2017-10-29.

## New Features

[#266](https://github.com/adobe-apiplatform/user-sync.py/issues/266): Extended attribute values (defined in extensions) can now be multi-valued. The type of the attribute value in the `source_attributes` dictionary will be:
* `None` if the attribute has no value;
* a `str` (or `unicode` in py2) if the attribute has one value;
* a `list` of `str` (or `unicode` in py2) if the attribute has multiple values.

[#268](https://github.com/adobe-apiplatform/user-sync.py/issues/268): To make sure users get all the right overlapping entitlements associated with mapped user groups, `--strategy push` now does group removals before group adds.
[#294](https://github.com/adobe-apiplatform/user-sync.py/issues/294): Show statistics about users added to secondaries.

## Bug Fixes

[#257](https://github.com/adobe-apiplatform/user-sync.py/issues/257): Catch exceptions thrown by umapi-client when creating actions.

[#258](https://github.com/adobe-apiplatform/user-sync.py/issues/258): Correctly decrypt private keys in py3.
[#283](https://github.com/adobe-apiplatform/user-sync.py/issues/283): Don't import keyring unless needed.

[#260](https://github.com/adobe-apiplatform/user-sync.py/issues/260): Make sure the requests library is loaded when using pex on Windows.
[#286](https://github.com/adobe-apiplatform/user-sync.py/issues/286): Allow specifying attributes for Adobe IDs.

[#265](https://github.com/adobe-apiplatform/user-sync.py/issues/265): Extended attributes in extensions couldn't be fetched unless they had non-ascii names.
[#288](https://github.com/adobe-apiplatform/user-sync.py/issues/288): Escape special characters in user input to LDAP queries.

[#269](https://github.com/adobe-apiplatform/user-sync.py/issues/269): When using `--strategy sync`, new users created in secondary organizations were not being added to any groups.
[#293](https://github.com/adobe-apiplatform/user-sync.py/issues/293): Don't crash when existing users are added to secondaries.

## Compatibility with Prior Versions

There are no functional changes from prior versions.
There are no interface changes from prior versions.

## Known Issues

Because the release on Windows is built with a pre-compiled version of pyldap, we have to specify a specific version to be used in each release. This not always be the latest version.
The nosetests are broken in this release candidate.

Because the release on Windows is built with a pre-compiled version of pyldap, we have to specify a specific version to be used in each release. This may not always be the latest version.

On the Win64 platform, there are very long pathnames embedded in the released build artifact `user-sync.pex`, which will cause problems unless you are on Windows 10 and are either running Python 3.6 or have enabled long pathnames system-wide (as described in this [Microsoft Dev Center article](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx)). To work around this issue on older platforms, set the `PEX_ROOT` environment variable (as described [in the docs here](https://adobe-apiplatform.github.io/user-sync.py/en/user-manual/setup_and_installation.html)) to be a very short path (e.g., `set PEX_ROOT=C:\pex`).

Each release on each platform is built with a specific version of Python. Typically this is the latest available (from the OS vendor, if they provide one) for that platform. In general, and especially on Windows, you should use the same Python to run User Sync as it was built with.
7 changes: 5 additions & 2 deletions docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
<ul>
{% assign current_level = my_page.nav_level %}
{% elsif my_page.nav_level < current_level %}
</ul>
{% assign current_level = my_page.nav_level %}
{% assign ub = current_level | minus: 1 %}
{% for i in (my_page.nav_level .. ub) %}
</ul>
{% endfor %}
{% assign current_level = my_page.nav_level %}
{% endif %}
{% if my_page.url == page.url %}
<li><a class="page-link selected-page-link" href="{{ my_page.url | relative_url }}">{{ my_page.nav_link | escape }}</a></li>
Expand Down
5 changes: 4 additions & 1 deletion examples/config files - basic/3 connector-ldap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ search_page_size: 200
require_tls_cert: False

# (optional) all_users_filter (default value given below)
# all_users_filter specifies the query used to find all users in the directory.
# Use this filter to control exactly which LDAP resources are considered for synchronization.
# If a user is not accepted by this filter he will never be seen by the User Sync tool, even if
# your command line specifies --users all or he is in a group you have specified in your
# command line (--users group g1) or in your configuration file (for group mapping).
# The default value specified here is appropriate for Active Directory, which has a
# special field that is used to enable and disable users. The value for OpenLDAP
# directories might be much simpler: "(&(objectClass=person)(objectClass=top))"
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
'pycryptodome',
'pyldap==2.4.37',
'PyYAML',
'umapi-client>=2.7',
'umapi-client>=2.8',
'psutil',
'keyring',
'six'
Expand Down
2 changes: 1 addition & 1 deletion user_sync/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import subprocess
import types

import keyring
import yaml
import six

Expand Down Expand Up @@ -600,6 +599,7 @@ def get_credential(self, name, user_name, none_allowed=False):
raise AssertionException('%s: cannot contain setting for both "%s" and "%s"' % (scope, name, keyring_name))
if secure_value_key:
try:
import keyring
value = keyring.get_password(service_name=secure_value_key, username=user_name)
except Exception as e:
raise AssertionException('%s: Error accessing secure storage: %s' % (scope, e))
Expand Down
33 changes: 31 additions & 2 deletions user_sync/connector/directory_ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def load_users_and_groups(self, groups, extended_attributes, all_users):
if not group_dn:
self.logger.warning("No group found for: %s", group)
continue
group_member_subfilter = group_member_filter_format.format(group_dn=group_dn)
group_member_subfilter = self.format_ldap_query_string(group_member_filter_format, group_dn=group_dn)
if not group_member_subfilter.startswith('('):
group_member_subfilter = six.text_type('(') + group_member_subfilter + six.text_type(')')
user_subfilter = all_users_filter
Expand Down Expand Up @@ -178,8 +178,9 @@ def find_ldap_group_dn(self, group):
base_dn = six.text_type(options['base_dn'])
group_filter_format = six.text_type(options['group_filter_format'])
try:
filter_string = self.format_ldap_query_string(group_filter_format, group=group)
res = connection.search_s(base_dn, ldap.SCOPE_SUBTREE,
filterstr=group_filter_format.format(group=group), attrsonly=1)
filterstr=filter_string, attrsonly=1)
except Exception as e:
raise AssertionException('Unexpected LDAP failure reading group info: %s' % e)
group_dn = None
Expand Down Expand Up @@ -324,6 +325,34 @@ def iter_search_result(self, base_dn, scope, filter_string, attributes):
connection.abandon(msgid)
raise

@staticmethod
def format_ldap_query_string(query, **kwargs):
"""
Escape LDAP special characters that may appear in injected query strings
Should be used with any string that will be injected into an LDAP query.
:param query:
:param kwargs:
:return:
"""
# See http://www.rfc-editor.org/rfc/rfc4515.txt
escape_chars = six.text_type('*()\\&|<>~!:')
escaped_args = {}
# kwargs is a dict that would normally be passed to string.format
for k, v in six.iteritems(kwargs):
# LDAP special characters are escaped in the general format '\' + hex(char)
# we need to run through the string char by char and if the char exists in
# the escape_char list, get the ord of it (decimal ascii value), convert it to hex, and
# replace the '0x' with '\'
escaped_list = []
for c in v:
if c in escape_chars:
replace = six.text_type(hex(ord(c))).replace('0x', '\\')
escaped_list.append(replace)
else:
escaped_list.append(c)
escaped_args[k] = six.text_type('').join(escaped_list)
return query.format(**escaped_args)


class LDAPValueFormatter(object):
encoding = 'utf8'
Expand Down
12 changes: 1 addition & 11 deletions user_sync/connector/umapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,6 @@ def update_user(self, attributes):
"""
:type attributes: dict
"""
if self.identity_type == user_sync.identity_type.ADOBEID_IDENTITY_TYPE:
# shouldn't happen, but ignore it if it does
return
if attributes is not None and len(attributes) > 0:
params = self.convert_user_attributes_to_params(attributes)
self.do_list.append(('update', params))
Expand Down Expand Up @@ -212,14 +209,7 @@ def add_user(self, attributes):
"""
:type attributes: dict
"""
if self.identity_type == user_sync.identity_type.ADOBEID_IDENTITY_TYPE:
email = self.email if self.email else self.username
if not email:
error_message = "ERROR: you must specify an email with an Adobe ID"
raise AssertionException(error_message)
params = self.convert_user_attributes_to_params({'email': email})
else:
params = self.convert_user_attributes_to_params(attributes)
params = self.convert_user_attributes_to_params(attributes)

on_conflict_value = None
option = params.pop('option', None)
Expand Down
Loading