Skip to content

Commit

Permalink
Merge pull request #3783 from privacyidea/3767b/added-token-descripti…
Browse files Browse the repository at this point in the history
…on-in-user-notification-event-handler

added token description in user notification event handler
  • Loading branch information
plettich committed Oct 23, 2023
2 parents 22c8b78 + 0aca89b commit 667ba37
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 12 deletions.
1 change: 1 addition & 0 deletions doc/eventhandler/usernotification.rst
Expand Up @@ -160,6 +160,7 @@ The body may contain the following tags
* {username} the loginname of the token owner.
* {userrealm} the realm of the token owner.
* {tokentype} the type of the token.
*{tokendescription} the description of the token.
* {registrationcode} the registration code in the detail response.
* {recipient_givenname} the given name of the recipient.
* {recipient_surname} the surname of the recipient.
Expand Down
9 changes: 7 additions & 2 deletions privacyidea/lib/eventhandler/usernotification.py
Expand Up @@ -39,6 +39,7 @@
The module is tested in tests/test_lib_eventhandler_usernotification.py
"""

from privacyidea.lib.eventhandler.base import BaseEventHandler
from privacyidea.lib.smtpserver import send_email_identifier
from privacyidea.lib.smsprovider.SMSProvider import send_sms_identifier
Expand Down Expand Up @@ -83,6 +84,7 @@ class NOTIFY_TYPE(object):
EMAIL = "email"
NO_REPLY_TO = ""


class UserNotificationEventHandler(BaseEventHandler):
"""
An Eventhandler needs to return a list of actions, which it can handle.
Expand Down Expand Up @@ -255,7 +257,7 @@ def do(self, action, options=None):
tokenowner = self._get_tokenowner(request)
log.debug("Executing event for action {0!r}, user {1!r}, "
"logged_in_user {2!r}".format(action, tokenowner,
logged_in_user))
logged_in_user))

# Determine recipient
recipient = None
Expand Down Expand Up @@ -390,10 +392,12 @@ def do(self, action, options=None):
googleurl_img = content.get("detail", {}).get("googleurl",
{}).get("img")
tokentype = None
tokendescription = None
if serial:
tokens = get_tokens(serial=serial)
if tokens:
tokentype = tokens[0].get_tokentype()
tokendescription = tokens[0].token.description
else:
token_objects = get_tokens(user=tokenowner)
serial = ','.join([tok.get_serial() for tok in token_objects])
Expand All @@ -407,6 +411,7 @@ def do(self, action, options=None):
tokenowner=tokenowner,
serial=serial,
tokentype=tokentype,
tokendescription=tokendescription,
registrationcode=registrationcode,
escape_html=action.lower() == "sendmail" and
handler_options.get("mimetype", "").lower() == "html")
Expand All @@ -422,7 +427,7 @@ def do(self, action, options=None):

if attach_qrcode and googleurl_img:
# get the image part of the googleurl
googleurl = urlopen(googleurl_img) # nosec B310 # no user input
googleurl = urlopen(googleurl_img) # nosec B310 # no user input
mail_body = MIMEMultipart('related')
mail_body.attach(MIMEText(body, mimetype))
mail_img = MIMEImage(googleurl.read())
Expand Down
13 changes: 8 additions & 5 deletions privacyidea/lib/utils/__init__.py
Expand Up @@ -58,9 +58,9 @@
ALLOWED_SERIAL = r"^[0-9a-zA-Z\-_]+$"

# character lists for the identifiers in the pin content policy
CHARLIST_CONTENTPOLICY = {"c": string.ascii_letters, # characters
"n": string.digits, # numbers
"s": string.punctuation} # special
CHARLIST_CONTENTPOLICY = {"c": string.ascii_letters, # characters
"n": string.digits, # numbers
"s": string.punctuation} # special


def check_time_in_range(time_range, check_time=None):
Expand Down Expand Up @@ -905,7 +905,7 @@ def int_to_hex(serial):
"""
serial_hex = hex(int(serial)).upper()
serial_hex = serial_hex.split("X")[1]
if len(serial_hex)%2 != 0:
if len(serial_hex) % 2 != 0:
serial_hex = "0" + serial_hex
return serial_hex

Expand All @@ -931,7 +931,7 @@ def parse_legacy_time(ts, return_date=False):
# we need to reparse the string
d = parse_date_string(ts,
dayfirst=re.match(r"^\d\d[/\.]", ts)).replace(
tzinfo=tzlocal())
tzinfo=tzlocal())
if return_date:
return d
else:
Expand Down Expand Up @@ -1335,6 +1335,7 @@ def create_tag_dict(logged_in_user=None,
serial=None,
tokenowner=None,
tokentype=None,
tokendescription=None,
recipient=None,
registrationcode=None,
googleurl_value=None,
Expand All @@ -1355,6 +1356,7 @@ def create_tag_dict(logged_in_user=None,
:param recipient: The recipient
:type recipient: dictionary with "givenname" and "surname"
:param registrationcode: The registration code of a token
:param tokendescription: The description of the token
:param googleurl_value: The URL for the QR code during token enrollemnt
:param client_ip: The IP of the client
:param pin: The PIN of a token
Expand All @@ -1376,6 +1378,7 @@ def create_tag_dict(logged_in_user=None,
username=tokenowner.login if tokenowner else "",
userrealm=tokenowner.realm if tokenowner else "",
tokentype=tokentype,
tokendescription=tokendescription,
registrationcode=registrationcode,
recipient_givenname=recipient.get("givenname"),
recipient_surname=recipient.get("surname"),
Expand Down
15 changes: 10 additions & 5 deletions tests/test_lib_eventhandler_usernotification.py
Expand Up @@ -82,13 +82,16 @@ def test_02_sendmail(self):
smtpmock.setdata(response={"recp@example.com": (200, "OK")},
support_tls=False)

tok = init_token({"serial": "SomeSerial", "description": "It works", "type": "spass"},
user=User("cornelius", "realm1"))

g = FakeFlaskG()
audit_object = FakeAudit()
audit_object.audit_data["serial"] = "123456"

g.logged_in_user = {"username": "admin",
g.logged_in_user = {"username": "cornelius",
"role": "admin",
"realm": ""}
"realm": "realm1"}
g.audit_object = audit_object

builder = EnvironBuilder(method='POST',
Expand All @@ -108,15 +111,17 @@ def test_02_sendmail(self):
options = {"g": g,
"request": req,
"response": resp,
"handler_def": {"options":
{"emailconfig": "myserver"}
"handler_def": {"options": {"subject": "token description: {tokendescription}"
" token serial: {serial}",
"emailconfig": "myserver"}
}
}

un_handler = UserNotificationEventHandler()
res = un_handler.do("sendmail", options=options)
self.assertTrue(res)
msg = smtpmock.get_sent_message()
self.assertIn("token description: It works token serial: SomeSerial", msg, msg)
assert 'To: user@localhost.localdomain' in msg

@smtpmock.activate
Expand Down Expand Up @@ -515,7 +520,7 @@ def test_10_check_conditions_token_validity_period(self):

tok = init_token({"serial": serial,
"type": "spass"},
user=User("cornelius", "realm1"))
user=User("cornelius", "realm1"))

env = builder.get_environ()
req = Request(env)
Expand Down

0 comments on commit 667ba37

Please sign in to comment.