This repository was archived by the owner on Sep 15, 2024. It is now read-only.
forked from dolfim/gitlab_user_creator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun.py
More file actions
207 lines (168 loc) · 6.89 KB
/
Copy pathrun.py
File metadata and controls
207 lines (168 loc) · 6.89 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# Copyright (C) 2016 Theoretical Physics, ETH Zurich
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from flask import Flask, flash, redirect, render_template, \
request, url_for, session
from flask_oauthlib.client import OAuth, parse_response
from wtforms import Form, TextField, validators, PasswordField
from wtforms.fields.html5 import EmailField
from wtforms.csrf.session import SessionCSRF
import requests, json
import string
import random
import smtplib
from email.mime.text import MIMEText
from email.header import Header
class ReverseProxied(object):
'''Wrap the application in this middleware and configure the
front-end server to add these headers, to let you quietly bind
this to a URL other than / and to an HTTP scheme that is
different than what is used locally.
In nginx:
location /myprefix {
proxy_pass http://192.168.0.1:5001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Script-Name /myprefix;
}
:param app: the WSGI application
'''
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]
scheme = environ.get('HTTP_X_SCHEME', '')
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)
app = Flask(__name__)
app.config.from_pyfile('settings.cfg')
app.wsgi_app = ReverseProxied(app.wsgi_app)
app.secret_key = 'some_secret'
oauth = OAuth()
remote_app = oauth.remote_app('remote_app',
base_url=app.config['GITLAB_BASE']+'/api/v3/',
request_token_url=None,
access_token_url=app.config['GITLAB_BASE']+'/oauth/token',
authorize_url=app.config['GITLAB_BASE']+'/oauth/authorize',
app_key='GITLAB',
access_token_method='POST'
)
oauth.init_app(app)
@remote_app.tokengetter
def get_gitlab_token():
return session.get('gitlab_token')
@app.route('/account')
def account():
logged_in = get_gitlab_token() is not None
next_url = request.args.get('next') or request.referrer
user = session['gitlab_user'] if 'gitlab_user' in session else None
return render_template('account.html', logged_in=logged_in, next_url=next_url, user=user)
@app.route('/account/login')
def login():
return remote_app.authorize(callback=url_for('oauth_authorized', _external=True,
next=request.args.get('next') or request.referrer or None))
@app.route('/account/logout')
def logout():
session.clear()
flash(u'You logged out successfully.')
return redirect(url_for('account'))
@app.route('/oauth-authorized')
def oauth_authorized():
resp = remote_app.authorized_response()
next_url = request.args.get('next') or url_for('index')
if resp is None:
flash(u'You denied the request to sign in.')
return redirect(next_url)
r = remote_app.get('user', token=(resp['access_token'],''))
if r.status != 200:
flash(u'Request of /user information failed.', 'error')
print r.text
return redirect(next_url)
user = r.data
if user['external']:
flash('The user %s is flagged as external.' % user['username'], 'error')
return redirect(next_url)
session['gitlab_token'] = (resp['access_token'], '')
session['gitlab_user'] = user
flash('You were signed in as %s' % user['username'])
return redirect(next_url)
def generate_password():
chars = string.letters + string.digits + string.punctuation
pwdSize = 10
return ''.join((random.choice(chars)) for x in range(pwdSize))
def send_confirmation_mail(data, sender_name='Gitlab'):
msgcontent = """Hello {name},
an Gitlab-Account was created for you!
Please sign in under {GITLAB_BASE} with the credentials
listed below and change your password!
Username: {username}
Password: {password}
Cheers,
{gitlab_user}
""".format(GITLAB_BASE=app.config['GITLAB_BASE'], gitlab_user=sender_name, **data)
msg = MIMEText(msgcontent, 'plain')
subj = Header('A Gitlab account has been created for you!')
msg['Subject'] = subj
msg['From'] = app.config['MAILSENDER']
msg['To'] = data['email']
msg['Content-Type'] = "text/html"
msg['Content-Transfer-Encoding'] = "quoted-printable"
try:
s = smtplib.SMTP('localhost')
except:
pass
else:
s.sendmail(app.config['MAILSENDER'], data['email'], msg.as_string())
s.quit()
class RegistrationForm(Form):
name = TextField('Name', [validators.Required()], render_kw={"placeholder": "Name"})
username = TextField('Username', [validators.Required()], render_kw={"placeholder": "Username"})
email = EmailField('Email Address', [validators.Required(), validators.Email()], render_kw={"placeholder": "Email"})
class Meta:
csrf = True
csrf_secret = app.config['CSRF_SECRET']
@app.route('/', methods=['GET', 'POST'])
def index():
token = get_gitlab_token()
if token is None:
return redirect(url_for('account', next=url_for('index')))
form = RegistrationForm(request.form, meta={'csrf_context': session})
if request.method == 'POST' and form.validate():
data = {}
data['name'] = form.name.data
data['username'] = form.username.data
data['email'] = form.email.data
data['password'] = generate_password()
data['projects_limit'] = 0
data['skip_confirmation'] = True
data['external'] = True
r = requests.post(app.config['GITLAB_BASE']+'/api/v4/users', data=json.dumps(data),
headers={'Private-Token': app.config['GITLAB_ADMIN_TOKEN'], 'content-type': 'application/json'})
if r.status_code == 201:
flash('The user {} has been successfully created.'.format(form.username.data), 'success')
send_confirmation_mail(data, session['gitlab_user']['name'])
else:
flash('Problems when creating the user: {}'.format(r.json()['message']), 'error')
return render_template('index.html', form=form, user=session['gitlab_user'])
@app.route('/test')
def test():
return "The URL for index page is {}".format(url_for("index"))
if __name__ == "__main__":
app.run()