Skip to content

Commit

Permalink
Windows Credential Manager implementation
Browse files Browse the repository at this point in the history
From @bhunut-adobe: adding keyring and using it to get ldap passwords from the Windows credential manager.
  • Loading branch information
adobeDan committed Apr 28, 2017
1 parent 43df910 commit ec6873f
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 2 deletions.
10 changes: 9 additions & 1 deletion examples/config files - basic/3 connector-ldap.yml
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@
# You must specify all four of these settings. Consult with your
# enterprise directory administrators to get suitable values.
# These access credentials are sensitive and must be protected.
username: "LDAP username goes here"
username: "LDAP or Credential Manager username goes here"
password: "LDAP password goes here"
host: "LDAP host URL goes here. e.g. ldap://ldap.example.com"
base_dn: "defines the base DN. e.g. DC=example,DC=com"

#(optional)
credential_manager:
#This will pull credential from Windows Credential Manager in Control Panel.
#value: windows_credential_manager
type: windows_credential_manager
#service_name is Required for Windows Credential Manger
service_name: "Internet or Network Address field in Credential Manager"

# (optional) user_identity_type (default is inherited from main configuration)
# user_identity_type specifies a default identity type for when directory users
# are created on the Adobe side (one of adobeID, enterpriseID, federatedID).
Expand Down
1 change: 1 addition & 0 deletions misc/build/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pycrypto
PyYAML
psutil
umapi-client>=2.0.2
keyring
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
'PyYAML',
'umapi-client>=2.2',
'psutil',
'keyring'
],
setup_requires=['nose>=1.0'],
tests_require=[
Expand Down
2 changes: 2 additions & 0 deletions user_sync/connector/directory_ldap.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def __init__(self, caller_options):
builder.require_string_value('base_dn')
options = builder.get_options()
password = caller_config.get_string('password')
# make sure credential_manager does not get reported as unused
caller_config.get_dict("credential_manager", True)

self.user_identity_type = user_sync.identity_type.parse_identity_type(options['user_identity_type'])
self.user_identity_type_formatter = LDAPValueFormatter(options['user_identity_type_format'])
Expand Down
23 changes: 22 additions & 1 deletion user_sync/credential_manager.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import keyring

from user_sync.error import AssertionException

UMAPI_CREDENTIAL_TYPE = "Adobe_UMAPI"
DIRECTORY_CREDENTIAL_TYPE = "Directory"
KEYRING_SUPPORTED = ['windows_credential_manager']

def get_credentials(credential_type, credential_id, **kwArgs):
'''
Expand All @@ -42,5 +46,22 @@ def get_credentials(credential_type, credential_id, **kwArgs):
:type kwArgs: dict
:rtype dict | str | None
'''
if credential_type == DIRECTORY_CREDENTIAL_TYPE:
config = kwArgs['config']
if 'credential_manager' in config:
cred_man = config['credential_manager']
if (cred_man.get('type') in KEYRING_SUPPORTED and
'service_name' in cred_man and 'username' in config):
return get_credentials_from_keyring(cred_man['service_name'], config['username'])
return None


def get_credentials_from_keyring(service_name, username):
try:
cred = keyring.get_password(service_name=service_name, username=username)
except Exception as e:
raise AssertionException("Error accessing credential manager: %s" % e)
if cred == None:
raise AssertionException("Unable to retrieve password for service_name: '%s' service_username: %s" % (service_name, username))
elif cred == "":
raise AssertionException ("Password is empty for service_name: '%s' service_username: %s" % (service_name, username))
return {'username': username, 'password': cred}

0 comments on commit ec6873f

Please sign in to comment.