Skip to content
Snippets Groups Projects
Commit 3200d606 authored by Václav Bartoš's avatar Václav Bartoš
Browse files

automatic send of email when user is added made optional (checkbox added)

parent 91ad527f
No related branches found
No related tags found
No related merge requests found
...@@ -3,11 +3,11 @@ import sys ...@@ -3,11 +3,11 @@ import sys
from datetime import datetime, timezone from datetime import datetime, timezone
import os.path import os.path
import re import re
from typing import List, Dict, Optional, Union from typing import List, Dict, Optional, Union, Tuple
from flask import Flask, render_template, request, make_response, redirect, flash, send_file from flask import Flask, render_template, request, make_response, redirect, flash, send_file
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import StringField from wtforms import StringField, BooleanField
from wtforms.validators import DataRequired, Email from wtforms.validators import DataRequired, Email
import requests import requests
...@@ -246,6 +246,13 @@ class AddUserForm(FlaskForm): ...@@ -246,6 +246,13 @@ class AddUserForm(FlaskForm):
lastname = StringField("Last name", validators=[]) lastname = StringField("Last name", validators=[])
email = StringField("Email", validators=[DataRequired(), Email()]) email = StringField("Email", validators=[DataRequired(), Email()])
# DN is constructed automatically from CN # DN is constructed automatically from CN
send_email = BooleanField("Automatically send email with an URL allowing the user to download his/her certificate.",
default="checked",
description="A certificate, signed by an internal SOCtools CA, is generated for each user. It allows "
"to access all the SOCtools components. The user can download the certificate "
"(and matching private key) on a unique URL which will be sent to given email address. "
"Check to send it immediately after the user account is created. Or you can (re)send it"
"manually later.")
@app.route("/") @app.route("/")
...@@ -310,9 +317,8 @@ def add_user(): ...@@ -310,9 +317,8 @@ def add_user():
try: try:
certificates.generate_certificate(user.cn) certificates.generate_certificate(user.cn)
flash(f'Certificate for user "{user.username}" was successfully created.', "success") flash(f'Certificate for user "{user.username}" was successfully created.', "success")
#token = certificates.generate_access_token(user.cn)
#print(f"Certificate access token for '{user.cn}': {token}")
# TODO: send token to email automatically?
except certificates.CertError as e: except certificates.CertError as e:
flash(str(e), "error") flash(str(e), "error")
return redirect("/") # don't continue creating user accounts in services return redirect("/") # don't continue creating user accounts in services
...@@ -323,6 +329,7 @@ def add_user(): ...@@ -323,6 +329,7 @@ def add_user():
flash(f'User "{user.username}" successfully created in Keycloak.', "success") flash(f'User "{user.username}" successfully created in Keycloak.', "success")
except Exception as e: except Exception as e:
flash(f'Error when creating user in Keycloak: {e}', "error") flash(f'Error when creating user in Keycloak: {e}', "error")
return redirect("/") # don't continue creating user accounts in other services
# NiFi # NiFi
try: try:
...@@ -342,6 +349,14 @@ def add_user(): ...@@ -342,6 +349,14 @@ def add_user():
except Exception as e: except Exception as e:
flash(f'Error when creating user in MISP: {e}', "error") flash(f'Error when creating user in MISP: {e}', "error")
# Send email to the user
if form_user.send_email.data:
ok, err = _send_token(user.username, user.email)
if ok:
flash(f"Email successfully sent to '{user.email}'", "success")
else:
flash(f"ERROR: {err}", "error")
return redirect("/") # Success - go back to main page return redirect("/") # Success - go back to main page
return render_template("add_edit_user.html", form_user=form_user, user=None) return render_template("add_edit_user.html", form_user=form_user, user=None)
...@@ -484,6 +499,7 @@ def send_token(username: str): ...@@ -484,6 +499,7 @@ def send_token(username: str):
""" """
Send an email with certificate access token to the user. Send an email with certificate access token to the user.
Endpoint called by a "send email" button from web gui.
""" """
# Check that the user exists # Check that the user exists
user_spec = kc_get_user_by_name(username) user_spec = kc_get_user_by_name(username)
...@@ -491,12 +507,25 @@ def send_token(username: str): ...@@ -491,12 +507,25 @@ def send_token(username: str):
flash(f"ERROR: No such user ('{username}')", "error") flash(f"ERROR: No such user ('{username}')", "error")
return redirect("/") return redirect("/")
ok, err = _send_token(username, user_spec.email)
if ok:
flash(f"Email successfully sent to '{user_spec.email}'", "success")
else:
flash(f"ERROR: {err}", "error")
return redirect("/")
def _send_token(username: str, email: str) -> Tuple[bool, Optional[str]]:
"""
Generate token and send the email (internal function)
:return tuple: success or not (bool), error message in case of failure
"""
# Generate token # Generate token
try: try:
token = certificates.generate_access_token(username) token = certificates.generate_access_token(username)
except Exception as e: except Exception as e:
flash(f"ERROR: {e}", "error") return False, str(e)
return redirect("/")
access_url = f"{config.USER_MGMT_BASE_URL}/export_certificate?token={token}" access_url = f"{config.USER_MGMT_BASE_URL}/export_certificate?token={token}"
print(f"Certificate access URL for '{username}': {access_url}") print(f"Certificate access URL for '{username}': {access_url}")
...@@ -504,15 +533,14 @@ def send_token(username: str): ...@@ -504,15 +533,14 @@ def send_token(username: str):
# Send the token via email # Send the token via email
# TODO # TODO
flash(f"Email successfully sent to '{user_spec.email}'", "success") return True, None
return redirect("/")
# TODO: # TODO:
# (re)send cert-access token for existing user - DONE (on click in table) # (re)send cert-access token for existing user - DONE (on click in table)
# automatically create certificate when creating new user (optionally automatically send email with token) - DONE # automatically create certificate when creating new user (optionally automatically send email with token) - DONE
# revoke and delete certificate when user is deleted # revoke and delete certificate when user is deleted
# make CN=username (co cert filename also matches the username (it's stored by CN)) # make CN=username (so cert filename also matches the username (it's stored by CN))
# @app.route("/test_cert/<func>") # @app.route("/test_cert/<func>")
......
...@@ -24,7 +24,12 @@ ...@@ -24,7 +24,12 @@
{{ form_user.lastname.label }} {{ form_user.lastname(size=20) }}<br> {{ form_user.lastname.label }} {{ form_user.lastname(size=20) }}<br>
{{ form_user.cn.label }} {{ form_user.cn(size=20) }}<br> {{ form_user.cn.label }} {{ form_user.cn(size=20) }}<br>
{{ form_user.email.label }} {{ form_user.email(size=20) }}<br> {{ form_user.email.label }} {{ form_user.email(size=20) }}<br>
<input type="submit" value="{{"Update user" if user else "Add user"}}"> {% if user %}
<input type="submit" value="Update user">
{% else %}
{{ form_user.send_email(title=form_user.send_email.description) }}{{ form_user.send_email.label(title=form_user.send_email.description) }}<br>
<input type="submit" value="Add user">
{% endif %}
</form> </form>
{% endblock %} {% endblock %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment