Skip to content

Commit 2f8f139

Browse files
committed
moved methods to the rigth blueprint path and added description to the blueprints.
1 parent 18ff5ed commit 2f8f139

11 files changed

Lines changed: 468 additions & 306 deletions

File tree

mslib/mscolab/app/__init__.py

Lines changed: 4 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@
2929
import sqlalchemy
3030

3131
from flask_migrate import Migrate
32-
from flask import Flask, Blueprint
32+
from flask import Flask
3333

3434
import mslib
3535

36-
from flask import render_template, send_from_directory, send_file, url_for, abort
36+
from flask import url_for
3737
from flask_sqlalchemy import SQLAlchemy
38+
39+
from mslib.mscolab.blueprints.docs.docs import DOCS_BP
3840
from mslib.mscolab.conf import mscolab_settings
3941
from mslib.utils import prefix_route, release_info
40-
from mslib.msui.icons import icons
4142
from mslib.utils.file_exists import file_exists
42-
from mslib.utils.get_content import get_content
4343
from xstatic.main import XStatic
4444

4545

@@ -51,12 +51,6 @@
5151
# This can be used to set a location by SCRIPT_NAME for testing. e.g. export SCRIPT_NAME=/demo/
5252
SCRIPT_NAME = os.environ.get('SCRIPT_NAME', '/')
5353

54-
DOCS_BP = Blueprint(
55-
"docs",
56-
__name__,
57-
template_folder=os.path.join(DOCS_TEMPLATES_DIR)
58-
)
59-
6054

6155
message, update = release_info.check_for_new_release()
6256
if update:
@@ -103,82 +97,6 @@ def create_app(imprint=None, gdpr=None):
10397
APP.jinja_env.globals["gdpr"] = gdpr_file
10498
APP.jinja_env.globals.update(get_topmenu=get_topmenu)
10599

106-
@DOCS_BP.route('/xstatic/<name>/<path:filename>')
107-
def files(name, filename):
108-
base_path = _xstatic(name)
109-
if base_path is None:
110-
abort(404)
111-
if not filename:
112-
abort(404)
113-
return send_from_directory(base_path, filename)
114-
115-
@DOCS_BP.route('/mss_theme/img/<path:filename>')
116-
def mss_theme(filename):
117-
base_path = os.path.join(DOCS_IMG_DIR)
118-
return send_from_directory(base_path, filename)
119-
120-
@DOCS_BP.route("/index")
121-
def index():
122-
return render_template("/index.html")
123-
124-
@DOCS_BP.route("/mss/about")
125-
@DOCS_BP.route("/mss")
126-
def about():
127-
_file = os.path.join(DOCS_DOCS_DIR, 'about.md')
128-
img_url = url_for('docs.overview')
129-
md_overrides = ('![image](/mss/overview.png)', f'![image]({img_url})')
130-
131-
html_overrides = ('<img alt="image" src="/mss/overview.png" />',
132-
'<img class="mx-auto d-block img-fluid" alt="image" src="/mss/overview.png" />')
133-
content = get_content(_file, md_overrides=md_overrides, html_overrides=html_overrides)
134-
return render_template("/content.html", act="about", content=content)
135-
136-
@DOCS_BP.route("/mss/install")
137-
def install():
138-
_file = os.path.join(DOCS_DOCS_DIR, 'installation.md')
139-
content = get_content(_file)
140-
return render_template("/content.html", act="install", content=content)
141-
142-
@DOCS_BP.route("/mss/help")
143-
def help(): # noqa: A001
144-
_file = os.path.join(DOCS_DOCS_DIR, 'help.md')
145-
html_overrides = ('<img alt="Waypoint Tutorial" '
146-
'src="https://mss.readthedocs.io/en/stable/_images/tutorial_waypoints.gif" />',
147-
'<img class="mx-auto d-block img-fluid" alt="Waypoint Tutorial" '
148-
'src="https://mss.readthedocs.io/en/stable/_images/tutorial_waypoints.gif" />')
149-
content = get_content(_file, html_overrides=html_overrides)
150-
return render_template("/content.html", act="help", content=content)
151-
152-
@DOCS_BP.route("/mss/imprint")
153-
def imprint():
154-
if file_exists(imprint_file):
155-
content = get_content(imprint_file)
156-
return render_template("/content.html", act="imprint", content=content)
157-
else:
158-
return ""
159-
160-
@DOCS_BP.route("/mss/gdpr")
161-
def gdpr():
162-
if file_exists(gdpr_file):
163-
content = get_content(gdpr_file)
164-
return render_template("/content.html", act="gdpr", content=content)
165-
else:
166-
return ""
167-
168-
@DOCS_BP.route('/mss/favicon.ico')
169-
def favicons():
170-
base_path = icons("16x16", "favicon.ico")
171-
return send_file(base_path)
172-
173-
@DOCS_BP.route('/mss/logo.png')
174-
def logo():
175-
base_path = icons("64x64", "mss-logo.png")
176-
return send_file(base_path)
177-
178-
@DOCS_BP.route('/mss/overview.png')
179-
def overview():
180-
base_path = os.path.join(DOCS_IMG_DIR, 'wise12_overview.png')
181-
return send_file(base_path)
182100
APP.register_blueprint(DOCS_BP)
183101
return APP
184102

mslib/mscolab/blueprints/auth/auth.py

Lines changed: 30 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,38 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
4+
mslib.mscolab.blueprints.auth.auth
5+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6+
7+
Auth Blueprint for server for mscolab module
8+
9+
This file is part of MSS.
10+
11+
:copyright: Copyright 2019 Shivashis Padhi
12+
:copyright: Copyright 2019-2026 by the MSS team, see AUTHORS.
13+
:license: APACHE-2.0, see LICENSE for details.
14+
15+
Licensed under the Apache License, Version 2.0 (the "License");
16+
you may not use this file except in compliance with the License.
17+
You may obtain a copy of the License at
18+
19+
http://www.apache.org/licenses/LICENSE-2.0
20+
21+
Unless required by applicable law or agreed to in writing, software
22+
distributed under the License is distributed on an "AS IS" BASIS,
23+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24+
See the License for the specific language governing permissions and
25+
limitations under the License.
26+
"""
27+
128
import datetime
2-
import functools
329
import json
430
import logging
531
import secrets
632

7-
import sqlalchemy
8-
import email_validator
9-
# Todo use the name email_validator
10-
from email_validator import validate_email
11-
from flask import Blueprint, request, url_for, render_template, jsonify, flash, redirect, abort, g
33+
from flask import Blueprint, request, url_for, render_template, jsonify, flash, redirect
1234
from flask_httpauth import HTTPBasicAuth
13-
from flask_mail import Message
1435
from flask.wrappers import Response
15-
from itsdangerous import URLSafeTimedSerializer, BadSignature
1636
from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST
1737
from saml2.metadata import create_metadata_string
1838

@@ -21,148 +41,8 @@
2141
from mslib.mscolab.models import User
2242
from mslib.mscolab.app import APP
2343
from mslib.utils import conditional_decorator
24-
25-
26-
def check_login(emailid, password):
27-
try:
28-
user = User.query.filter_by(emailid=str(emailid)).first()
29-
except sqlalchemy.exc.OperationalError as ex:
30-
logging.debug("Problem in the database (%ex), likely version client different", ex)
31-
return False
32-
if user is not None:
33-
if APP.config['MAIL_ENABLED']:
34-
if user.confirmed:
35-
if user.verify_password(password):
36-
return user
37-
else:
38-
if user.verify_password(password):
39-
return user
40-
return False
41-
42-
43-
def register_user(email, password, username, fullname):
44-
if len(str(email.strip())) == 0 or len(str(username.strip())) == 0:
45-
return {"success": False, "message": "Your username or email cannot be empty"}
46-
is_valid_username = True if username.find("@") == -1 else False
47-
try:
48-
# ToDo verify what changed for check_deliverability
49-
validate_email(email, check_deliverability=APP.config['MAIL_ENABLED'])
50-
except (email_validator.exceptions.EmailSyntaxError):
51-
return {"success": False, "message": "Your email ID is not valid!"}
52-
if not is_valid_username:
53-
return {"success": False, "message": "Your username cannot contain @ symbol!"}
54-
user_exists = User.query.filter_by(emailid=str(email)).first()
55-
if user_exists:
56-
return {"success": False, "message": "This email ID is already taken!"}
57-
user_exists = User.query.filter_by(username=str(username)).first()
58-
if user_exists:
59-
return {"success": False, "message": "This username is already registered"}
60-
from mslib.mscolab.server import getConfig
61-
fm = getConfig()[3]
62-
user = User(email, username, password, fullname)
63-
result = fm.modify_user(user, action="create")
64-
return {"success": result}
65-
66-
67-
def generate_confirmation_token(email):
68-
serializer = URLSafeTimedSerializer(APP.config['SECRET_KEY'])
69-
return serializer.dumps(email, salt=APP.config['SECURITY_PASSWORD_SALT'])
70-
71-
72-
def send_email(to, subject, template):
73-
if APP.config['MAIL_DEFAULT_SENDER'] is not None:
74-
msg = Message(
75-
subject,
76-
recipients=[to],
77-
html=template,
78-
sender=APP.config['MAIL_DEFAULT_SENDER']
79-
)
80-
try:
81-
from mslib.mscolab.server import getConfig
82-
mail = getConfig()[4]
83-
mail.send(msg)
84-
except IOError:
85-
logging.error("Can't send email to %s", to)
86-
else:
87-
logging.debug("setup user verification by email")
88-
89-
90-
def confirm_token(token, expiration=3600):
91-
serializer = URLSafeTimedSerializer(APP.config['SECRET_KEY'])
92-
try:
93-
email = serializer.loads(
94-
token,
95-
salt=APP.config['SECURITY_PASSWORD_SALT'],
96-
max_age=expiration
97-
)
98-
except (IOError, BadSignature):
99-
return False
100-
return email
101-
102-
103-
def get_idp_entity_id(selected_idp):
104-
"""
105-
Finds the entity_id from the configured IDPs
106-
:return: the entity_id of the idp or None
107-
"""
108-
for config in setup_saml2_backend.CONFIGURED_IDPS:
109-
if selected_idp == config['idp_identity_name']:
110-
idps = config['idp_data']['saml2client'].metadata.identity_providers()
111-
only_idp = idps[0]
112-
entity_id = only_idp
113-
return entity_id
114-
return None
115-
116-
117-
def create_or_update_idp_user(email, username, token, authentication_backend):
118-
"""
119-
Creates or updates an idp user in the system based on the provided email,
120-
username, token, and authentication backend.
121-
:param email: idp users email
122-
:param username: idp users username
123-
:param token: authentication token
124-
:param authentication_backend: authenticated identity providers name
125-
:return: bool : query success or not
126-
"""
127-
from mslib.mscolab.server import getConfig
128-
fm = getConfig()[3]
129-
user = User.query.filter_by(emailid=email).first()
130-
if not user:
131-
# using an IDP for a new account/profile, e-mail is already verified by the IDP
132-
confirm_time = datetime.datetime.now(tz=datetime.timezone.utc) + datetime.timedelta(seconds=1)
133-
user = User(email, username, password=token, confirmed=True, confirmed_on=confirm_time,
134-
authentication_backend=authentication_backend)
135-
result = fm.modify_user(user, action="create")
136-
else:
137-
user.authentication_backend = authentication_backend
138-
user.hash_password(token)
139-
result = fm.modify_user(user, action="update_idp_user")
140-
return result
141-
142-
143-
def verify_user(func):
144-
@functools.wraps(func)
145-
def wrapper(*args, **kwargs):
146-
try:
147-
user = User.verify_auth_token(request.args.get('token', request.form.get('token', False)))
148-
except TypeError:
149-
logging.debug("no token in request form")
150-
abort(404)
151-
if not user:
152-
return "False"
153-
else:
154-
# saving user details in flask.g
155-
if APP.config['MAIL_ENABLED']:
156-
if user.confirmed:
157-
g.user = user
158-
return func(*args, **kwargs)
159-
else:
160-
return "False"
161-
else:
162-
g.user = user
163-
return func(*args, **kwargs)
164-
return wrapper
165-
44+
from mslib.utils.auth import check_login, register_user, generate_confirmation_token, send_email, confirm_token, \
45+
get_idp_entity_id, create_or_update_idp_user
16646

16747
AUTH_BP = Blueprint('auth', __name__)
16848
auth_basic_auth = HTTPBasicAuth()

0 commit comments

Comments
 (0)