Skip to content

Commit 8e2bcaa

Browse files
author
Harry Kantas
committed
initial codebase push
1 parent f862420 commit 8e2bcaa

20 files changed

+1833
-0
lines changed

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## PROJECT SPECIFIC SECTION
2+
3+
# Ignore config files
4+
config/config.yml
5+
6+
# Ignore GApps keyfiles
7+
config/google_api_service_account_keyfile.json
8+
9+
# Ignore static JS libs
10+
static/bower_components/*
11+
12+
13+
## MISC FILES SECTION
14+
115
# Temp files
216
*#
317
.#*
@@ -20,6 +34,9 @@ dist
2034
.pids
2135
.pants.workdir.file_lock
2236

37+
38+
## GITHUB TEMPLATE SECTION
39+
2340
# Byte-compiled / optimized / DLL files
2441
__pycache__/
2542
*.py[cod]

3rdparty/python/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python_requirements()

3rdparty/python/requirements.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
certifi==2017.11.5
2+
chardet==3.0.4
3+
click==6.7
4+
Flask==0.12.2
5+
Flask-WTF==0.14.2
6+
gevent==1.2.2
7+
google-api-python-client==1.6.4
8+
greenlet==0.4.12
9+
gunicorn==19.7.1
10+
httplib2==0.10.3
11+
idna==2.6
12+
itsdangerous==0.24
13+
Jinja2==2.10
14+
MarkupSafe==1.0
15+
mock==2.0.0
16+
oauth2client==4.1.2
17+
pyasn1==0.4.2
18+
pyasn1-modules==0.2.1
19+
pycrypto==2.6.1
20+
python-ldap==3.1.0
21+
PyYAML==3.12
22+
requests==2.18.4
23+
rsa==3.4.2
24+
six==1.11.0
25+
simplejson==3.15.0
26+
SocksiPy-branch==1.1
27+
twitter.common.app==0.3.9
28+
twitter.common.collections==0.3.9
29+
twitter.common.contextutil==0.3.9
30+
twitter.common.dirutil==0.3.9
31+
twitter.common.lang==0.3.9
32+
twitter.common.log==0.3.9
33+
twitter.common.options==0.3.9
34+
twitter.common.process==0.3.9
35+
twitter.common.string==0.3.9
36+
twitter.common.util==0.3.9
37+
uritemplate==3.0.0
38+
urllib3==1.22
39+
Werkzeug==0.13
40+
WTForms==2.1

BUILD

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
python_binary(
2+
name = "gate-keeping-service",
3+
source = "gate_keeping_service.py",
4+
zip_safe = False,
5+
dependencies = [
6+
":gatekeeper_dependencies",
7+
],
8+
)
9+
10+
python_library(
11+
name = "gatekeeper_dependencies",
12+
sources = globs("*.py", "templates/*"),
13+
dependencies = [
14+
"3rdparty/python:twitter.common.app",
15+
"3rdparty/python:twitter.common.log",
16+
"3rdparty/python:Flask",
17+
"3rdparty/python:Flask-WTF",
18+
"3rdparty/python:MarkupSafe",
19+
"3rdparty/python:WTForms",
20+
"3rdparty/python:gevent",
21+
"3rdparty/python:greenlet",
22+
"3rdparty/python:pycrypto",
23+
"lib:pagerduty",
24+
"lib:google_api",
25+
"lib:gunicorn_wrapper",
26+
"lib:ldap_client"
27+
],
28+
)
29+
30+
python_binary(
31+
name = "runner",
32+
source = "runner.py",
33+
dependencies = [
34+
":runner_dependencies",
35+
],
36+
)
37+
38+
python_library(
39+
name = "runner_dependencies",
40+
sources = globs("runner.py"),
41+
dependencies = [
42+
"3rdparty/python:twitter.common.log",
43+
"3rdparty/python:pycrypto",
44+
"lib:pagerduty",
45+
"lib:google_api",
46+
"lib:ldap_client"
47+
],
48+
)
49+

config/config.example.yml

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
defaults:
2+
# Environment used. Choose between 'production' and 'testing'.
3+
environment: "testing"
4+
base_dir: "."
5+
use_https: false
6+
debug: true
7+
flask_secret: "CHANGE_ME"
8+
http_proxy:
9+
use_proxy: false
10+
proxy_url: "CHANGE_ME"
11+
proxy_port: 8080
12+
proxy_user: "CHANGE_ME"
13+
proxy_pass: "CHANGE_ME"
14+
15+
ldap:
16+
base_dn: "CHANGE_ME"
17+
pass: "CHANGE_ME"
18+
uri: "CHANGE_ME"
19+
user: "CHANGE_ME"
20+
queries:
21+
all_users: "CHANGE_ME"
22+
user_is_valid: "CHANGE_ME"
23+
user_is_active: "CHANGE_ME"
24+
user_info: "(uid=USER)"
25+
fields:
26+
full_name: "cn"
27+
first_name: "givenName"
28+
role: "CHANGE_ME"
29+
team: "CHANGE_ME"
30+
org: "CHANGE_ME"
31+
location: "CHANGE_ME"
32+
start_date: "CHANGE_ME"
33+
uid_number: "uidNumber"
34+
groups: "memberOf"
35+
photo_url: "CHANGE_ME"
36+
37+
pagerduty:
38+
base_url: "https://api.pagerduty.com/"
39+
api_key: "CHANGE_ME"
40+
41+
google_apps:
42+
admin_user: "gate-keeping-admin"
43+
domain: "testdomain.com"
44+
credentials_keyfile: "google_api_service_account_keyfile.json"
45+
api_scopes:
46+
- "https://www.googleapis.com/auth/admin.directory.user"
47+
- "https://www.googleapis.com/auth/admin.directory.user.security"
48+
- "https://www.googleapis.com/auth/admin.directory.group.member"
49+
- "https://www.googleapis.com/auth/gmail.settings.basic"
50+
- "https://www.googleapis.com/auth/gmail.settings.sharing"
51+
- "https://www.googleapis.com/auth/calendar"
52+
- "https://www.googleapis.com/auth/drive"
53+
54+
# Note: the items in the following lists MUST match the names of the fields for each form
55+
# See forms.py for more info.
56+
actions:
57+
google_admin: &google_admin
58+
RESET_PASSWORD: true
59+
DELETE_ASPS: true
60+
DELETE_TOKENS: true
61+
INVALIDATE_BACKUP_CODES: true
62+
ORG_UNIT_CHANGE: true
63+
ORG_UNIT_RESET: true
64+
google_gmail: &google_gmail
65+
SET_OOO_MSG: false
66+
DISABLE_IMAP: true
67+
DISABLE_POP: true
68+
google_calendar: &google_calendar
69+
CHANGE_EVENTS_OWNERSHIP: true
70+
REMOVE_FUTURE_EVENTS: true
71+
google_drive: &google_drive
72+
NEW_FILES_OWNER: true
73+
FILE_SEARCH: true
74+
pagerduty: &pagerduty
75+
REMOVE_FROM_ONCALLS: true
76+
duo: &duo
77+
REMOVE_FROM_DUO: false
78+
79+
action_groups:
80+
offboard:
81+
<<: *google_admin
82+
<<: *google_gmail
83+
<<: *google_calendar
84+
<<: *pagerduty
85+
lost_asset:
86+
- RESET_PASSWORD
87+
- DELETE_ASPS
88+
- DELETE_TOKENS
89+
- INVALIDATE_BACKUP_CODES
90+
- DISABLE_IMAP
91+
- DISABLE_POP

config/gate_keeping_service.aurora

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
run_service = Process(
2+
name = 'run_service',
3+
cmdline = '''
4+
chmod +x ./gate-keeping-service.pex &&
5+
unzip ./gate-keeping-service.pex &&
6+
unzip -o ./gate-keeping-service-res.zip &&
7+
./gate-keeping-service.pex --port {{thermos.ports[http]}} --env {{environment}}
8+
''')
9+
10+
stage_src = Packer.copy('gate-keeping-service')
11+
stage_res = Packer.copy('gate-keeping-service-res')
12+
13+
task = SequentialTask(
14+
name = 'gate-keeping-service',
15+
processes = [stage_src, stage_res, run_service],
16+
resources = Resources(cpu = 2, ram = 8 * GB, disk = 1 * GB))
17+
18+
job = Service(
19+
name = 'gate-keeping-service',
20+
task = task,
21+
role = 'gate-keeping-services',
22+
contact = 'CHANGE_ME',
23+
announce = Announcer(),
24+
constraints = job_constraints)
25+
26+
jobs = [
27+
job(cluster = 'dc1', environment = 'devel', instances = 1),
28+
job(cluster = 'dc2a', environment = 'test', instances = 1),
29+
job(cluster = 'dc2b', environment = 'test', instances = 1),
30+
job(cluster = 'dc3a', environment = 'prod', instances = 1),
31+
job(cluster = 'dc3b', environment = 'prod', instances = 1),
32+
]

forms.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from flask_wtf import FlaskForm
2+
from wtforms import BooleanField, StringField, TextAreaField, validators
3+
4+
5+
"""
6+
Note: field names must match the method names used by the various API client libraries.
7+
Libraries are located under twexit/lib.
8+
"""
9+
10+
11+
class BaseForm(FlaskForm):
12+
def __iter__(self):
13+
token = self.csrf_token
14+
yield token
15+
16+
field_names = {token.name}
17+
for cls in self.__class__.__bases__:
18+
for field in cls():
19+
field_name = field.name
20+
if field_name not in field_names:
21+
field_names.add(field_name)
22+
yield self[field_name]
23+
24+
for field_name in self._fields:
25+
if field_name not in field_names:
26+
yield self[field_name]
27+
28+
29+
class UserIdForm(BaseForm):
30+
USER_ID = StringField('LDAP user name', [validators.DataRequired(), validators.Length(min=2)])
31+
32+
33+
class GoogleAdminApiForm(BaseForm):
34+
RESET_PASSWORD = BooleanField('Reset Google apps password')
35+
DELETE_ASPS = BooleanField('Purge application specific passwords')
36+
DELETE_TOKENS = BooleanField('Purge 3rd party access tokens')
37+
INVALIDATE_BACKUP_CODES = BooleanField('Invalidate backup codes')
38+
ORG_UNIT_CHANGE = BooleanField('Move to Offboarded OU')
39+
ORG_UNIT_RESET = BooleanField('Restore move to Offboarded OU')
40+
41+
42+
class GoogleGmailApiForm(BaseForm):
43+
SET_OOO_MSG = BooleanField('Set Out Of Office message')
44+
OOO_MSG_TEXT = TextAreaField('Message text', [validators.Length(min=2)])
45+
DISABLE_IMAP = BooleanField('Disable IMAP email')
46+
DISABLE_POP = BooleanField('Disable POP email')
47+
48+
49+
class GoogleCalendarApiForm(BaseForm):
50+
CHANGE_EVENTS_OWNERSHIP = BooleanField('Change events ownership')
51+
GCAL_NEW_OWNER = StringField('LDAP of new owner', [validators.Length(min=2)])
52+
REMOVE_FUTURE_EVENTS = BooleanField('Delete future dated events')
53+
54+
55+
class PagerDutyApiForm(BaseForm):
56+
REMOVE_FROM_ONCALLS = BooleanField('Remove from OnCall rotas')
57+
58+
59+
class DuoApiForm(BaseForm):
60+
REMOVE_FROM_DUO = BooleanField('Remove from DUO')
61+
62+
63+
class GoogleApiForms(GoogleAdminApiForm, GoogleGmailApiForm, GoogleCalendarApiForm):
64+
pass
65+
66+
67+
class OffboardForm(UserIdForm, GoogleApiForms, PagerDutyApiForm, DuoApiForm):
68+
pass
69+
70+
71+
class LostAssetForm(UserIdForm, GoogleAdminApiForm, GoogleGmailApiForm):
72+
pass
73+
74+
75+
class GoogleMailForwardingForm(BaseForm):
76+
SET_MAIL_FORWARDING = BooleanField('Set a mail forwarding address')
77+
78+
79+
class GoogleDriveForm(BaseForm):
80+
FILE_SEARCH = StringField('File Search Query', [validators.Length(min=2)])
81+
NEW_OWNER = StringField('New files owner', [validators.DataRequired(), validators.Length(min=2)])
82+
83+
84+
class FilesOwnershipTransferForm(UserIdForm, GoogleDriveForm):
85+
pass

0 commit comments

Comments
 (0)