forked from Lapin-Blanc/samba_gsync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sync.py
executable file
·138 lines (117 loc) · 4.51 KB
/
sync.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
# the script should not fail to preserve the monitoring loop
# instead, if an exception occurs, we log the exception message and
# return a string with the expected format, signaling the error
from exceptions import Exception
try:
import os
import sys
import logging
import httplib2
from httplib import ResponseNotReady
import json
import re
from ldif3 import LDIFParser
from apiclient import discovery
from ggl.credentials import get_credentials
log_dir = "/var/log/samba_sync"
working_dir = os.path.dirname(os.path.realpath(__file__))
if not os.path.exists(log_dir):
os.makedirs(log_dir)
logging.basicConfig(filename=os.path.join(log_dir,'sync.log'),level=logging.INFO)
config = json.load(open(os.path.join(working_dir, 'config.json')))
DOMAIN = config['domain']
BUILD_DICT = {
"name": {
"familyName": "",
"givenName": "",
},
"password": "",
"primaryEmail": "",
"hashFunction": "crypt"
}
UPDATE_DICT = {
"name": {
"familyName": "",
"givenName": "",
},
"hashFunction": "crypt",
"password": ""
}
cred = get_credentials()
logging.warning("============== Sync script start ==================")
# logging.getLogger('googleapicliet.discovery_cache').setLevel(logging.ERROR)
# Google directory service
retry = True
while retry:
try:
http = cred.authorize(httplib2.Http())
service = discovery.build('admin', 'directory_v1', http=http, cache_discovery=False)
logging.info("Google service instanciated")
retry = False
except ResponseNotReady:
logging.info("Google service not ready, retrying")
# Raw user list
users = service.users().list(customer="my_customer").execute()['users']
# List of existing users (emails)
g_users = [u['primaryEmail'] for u in users]
logging.info("Google accounts list retrieved {}".format(g_users))
protected_accounts = [acc+"@"+DOMAIN for acc in config['protected_accounts']]
logging.info("Protected accounts list : {}".format(g_users))
# Parsing stdin as ldif
parsed = LDIFParser(sys.stdin).parse()
datas = parsed.next()
data_dict = datas[1]
account_name = data_dict.get("sAMAccountName", False)
if (account_name):
account_name = account_name[0]
primaryEmail = account_name + "@" + DOMAIN
# if no givenName, we use account_name
givenName = data_dict.get('givenName', account_name)
# if no familyName, we use account_name
familyName = data_dict.get('sn', account_name)
passwd = data_dict.get("virtualCryptSHA512", False)
if (passwd):
passwd = passwd[0]
match = re.match("^\{CRYPT\}(.*)$", passwd)
passwd = match.group(1)
deleted = data_dict.get("isDeleted", False)
if deleted:
deleted = data_dict.get("isDeleted")[0] == 'TRUE'
logging.info("ACCOUNT : {}".format(account_name))
logging.info("PASSWORD : {}".format(passwd))
logging.info("DELETED : {}".format(deleted))
# real user, either with password or planned for deletion
if ( account_name and (passwd or deleted) ):
# user to delete exists in the google domain and are not protected
if ( deleted and (primaryEmail in g_users) and not (primaryEmail in protected_accounts)):
logging.info("User {} is about to be deleted...".format(primaryEmail))
results = service.users().delete( userKey=primaryEmail ).execute()
logging.info(results)
logging.warning("User {} deleted !".format(primaryEmail))
# we have to make sure this is not a localy only deletion
elif ( not deleted ):
if ( primaryEmail in g_users ):
logging.info("User {} already present, updating password...".format(primaryEmail))
UPDATE_DICT["password"] = passwd
UPDATE_DICT['name']['givenName'] = givenName
UPDATE_DICT['name']['familyName'] = familyName
results = service.users().update(userKey=primaryEmail, body=UPDATE_DICT).execute()
logging.info(results)
logging.warning("Password updated for {} !".format(primaryEmail))
else:
BUILD_DICT['primaryEmail'] = primaryEmail
BUILD_DICT['name']['givenName'] = givenName
BUILD_DICT['name']['familyName'] = familyName
BUILD_DICT['password'] = passwd
logging.info("Creating user {}...".format(primaryEmail))
results = service.users().insert(body=BUILD_DICT).execute()
logging.info(results)
logging.warning("User {} created !".format(primaryEmail))
logging.warning("============== Sync script end ==================")
# needed for the sync script to end gracefully
print('DONE-EXIT: processed {} !'.format(account_name))
except Exception as e:
logging.error(e.message)
# needed for the sync script to end gracefully
print('DONE-EXIT: processed with errors, see the logs for details')