Skip to content

Commit f23a2dc

Browse files
author
anatoliis
committed
Flask plugin init commit
1 parent 3d25dbc commit f23a2dc

23 files changed

+608
-0
lines changed

plugins/flask_yoti/LICENSE

Whitespace-only changes.

plugins/flask_yoti/MANIFEST.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include LICENSE
2+
include README.md
3+
recursive-include flask_yoti/templates *.html
4+
recursive-include example/templates *.html

plugins/flask_yoti/README.md

Whitespace-only changes.

plugins/flask_yoti/example/app.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import os
2+
3+
from flask import Flask, render_template, session
4+
from flask_yoti import flask_yoti_blueprint
5+
from flask_yoti.decorators import yoti_authenticated
6+
7+
YOTI_APPLICATION_ID = os.environ.get('YOTI_APPLICATION_ID')
8+
9+
app = Flask(__name__)
10+
app.secret_key = os.urandom(24)
11+
12+
app.config.update(
13+
YOTI_APPLICATION_ID=YOTI_APPLICATION_ID,
14+
YOTI_VERIFICATION_KEY=os.environ.get('YOTI_VERIFICATION_KEY'),
15+
YOTI_CLIENT_SDK_ID=os.environ.get('YOTI_CLIENT_SDK_ID'),
16+
YOTI_KEY_FILE_PATH=os.environ.get('YOTI_KEY_FILE_PATH'),
17+
YOTI_LOGIN_VIEW='login',
18+
YOTI_REDIRECT_TO='profile'
19+
)
20+
21+
app.register_blueprint(flask_yoti_blueprint, url_prefix='/yoti')
22+
23+
24+
@app.route('/')
25+
def index():
26+
return render_template('index.html', app_id=YOTI_APPLICATION_ID)
27+
28+
29+
@app.route('/login')
30+
def login():
31+
return render_template('login.html')
32+
33+
34+
@app.route('/profile')
35+
@yoti_authenticated
36+
def profile():
37+
user_profile = session.get('yoti_user_profile', {})
38+
return render_template('profile.html', **user_profile)
39+
40+
41+
if __name__ == '__main__':
42+
app.run(debug=True)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<!-- Your header content -->
5+
<script src="https://sdk.yoti.com/clients/browser.js"></script>
6+
<meta charset="UTF-8">
7+
<title>Index</title>
8+
</head>
9+
10+
<body style="background-color:papayawhip;">
11+
<!-- Your website content -->
12+
13+
<!-- This span will create the Yoti button -->
14+
Button: {{ yoti_login_button('small', 'Custom label') }}
15+
16+
<!-- This script snippet will also be required in your HTML body during the early pilot period -->
17+
<script>
18+
_ybg.config.service = 'https://www.yoti.com/connect/';
19+
_ybg.init();
20+
</script>
21+
</body>
22+
</html>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="yoti-site-verification" content="{{ verification_key }}">
6+
<title>PROFILE</title>
7+
</head>
8+
<body style="background-color:papayawhip;">
9+
<h3><a href="/">Home</a></h3>
10+
<table>
11+
{% if user_id %}
12+
<tr>
13+
<td>USER ID:</td>
14+
<td>{{user_id}}</td>
15+
</tr>
16+
{% endif %}
17+
18+
{% if selfie %}
19+
<tr>
20+
<td>SELFIE:</td>
21+
<td><img width="200" alt="photo" src="{{selfie}}" /></td>
22+
</tr>
23+
{% endif %}
24+
25+
{% if phone_number %}
26+
<tr>
27+
<td>PHONE:</td>
28+
<td>{{phone_number}}</td>
29+
</tr>
30+
{% endif %}
31+
32+
{% if names %}
33+
<tr>
34+
<td>NAMES:</td>
35+
<td>{{names}}</td>
36+
</tr>
37+
{% endif %}
38+
39+
{% if birthdate %}
40+
<tr>
41+
<td>DATE OF BIRTH</td>
42+
<td>{{birthdate}}</td>
43+
</tr>
44+
{% endif %}
45+
46+
{% if nationality %}
47+
<tr>
48+
<td>NATIONALITY</td>
49+
<td>{{nationality}}</td>
50+
</tr>
51+
{% endif %}
52+
53+
{% if gender %}
54+
<tr>
55+
<td>GENDER</td>
56+
<td>{{gender}}</td>
57+
</tr>
58+
{% endif %}
59+
</table>
60+
</body>
61+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .flask_yoti import flask_yoti_blueprint
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from flask import Markup
2+
3+
from .login_button import get_login_button_html
4+
from .settings import get_config_value
5+
6+
7+
def yoti_context():
8+
context = login_button_context()
9+
context.update(site_verification_context())
10+
context.update(application_context())
11+
return context
12+
13+
14+
def login_button_context():
15+
return {
16+
'yoti_login_button': get_login_button_html,
17+
'yoti_login_button_sm': get_login_button_html('small'),
18+
'yoti_login_button_md': get_login_button_html('medium'),
19+
'yoti_login_button_lg': get_login_button_html('large')
20+
}
21+
22+
23+
def site_verification_context():
24+
verification_key = get_config_value('YOTI_VERIFICATION_KEY')
25+
raw_text = '<meta name="yoti-site-verification" content="{0}">'.format(
26+
verification_key
27+
)
28+
return {'yoti_site_verification': Markup(raw_text)}
29+
30+
31+
def application_context():
32+
yoti_application_id = get_config_value('YOTI_APPLICATION_ID')
33+
return {'yoti_application_id': yoti_application_id}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from time import time
2+
3+
4+
class ActivityDetailsStorage(object):
5+
6+
def __init__(self):
7+
self.storage = {}
8+
self._timestamps = {}
9+
self._timeout_sec = 15
10+
11+
def save(self, activity_details):
12+
user_id = activity_details.user_id
13+
self.storage[user_id] = activity_details
14+
self._timestamps[user_id] = time() + self._timeout_sec
15+
16+
def get(self, user_id):
17+
self._clear_outdated()
18+
return self.storage.pop(user_id, None)
19+
20+
def _clear_outdated(self):
21+
current_time = time()
22+
to_remove = []
23+
for user_id, timestamp in self._timestamps.items():
24+
if timestamp <= current_time:
25+
to_remove.append(user_id)
26+
27+
for user_id in to_remove:
28+
del self.storage[user_id]
29+
del self._timestamps[user_id]
30+
31+
32+
activity_details_storage = ActivityDetailsStorage()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from functools import wraps
2+
from flask import redirect, session, url_for
3+
from flask.sessions import SecureCookieSession
4+
5+
from .context_storage import activity_details_storage
6+
from .settings import get_config_value
7+
8+
9+
def yoti_authenticated(view_func):
10+
@wraps(view_func)
11+
def _decorated(*args, **kwargs):
12+
user_id = session.get('yoti_user_id')
13+
if isinstance(session, SecureCookieSession):
14+
activity_details = session.get('activity_details')
15+
else:
16+
activity_details = activity_details_storage.get(user_id)
17+
if not activity_details or activity_details.outcome != 'SUCCESS':
18+
yoti_login_view = get_config_value('YOTI_LOGIN_VIEW')
19+
return redirect(url_for(yoti_login_view))
20+
21+
session['yoti_user_id'] = activity_details.user_id
22+
session['yoti_user_profile'] = activity_details.user_profile
23+
24+
return view_func(*args, **kwargs)
25+
26+
return _decorated

0 commit comments

Comments
 (0)