Email with template

I’ve verified the email challenge-response feature. The user gets the briefest of all possible emails with “<otp>”. Now I want to build out that email with the use of an external template. I followed the example exactly, down to the file:/etc/privacyidea/emailtemplate.html name. The file is world-readable.

Now the C-R fails, and it looks like it is because of some low-level issue in processing the template file. I turned on DEBUG logging and this is what I see:

[2019-09-13 00:20:06,934][27530][139931553847040][WARNING][privacyidea.lib.tokens.emailtoken:294] The PIN was correct, but the EMail could not be sent: KeyError(u'user',)
[2019-09-13 00:20:06,936][27530][139931553847040][DEBUG][privacyidea.lib.tokens.emailtoken:295] Traceback (most recent call last):
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 289, in create_challenge mimetype=mimetype)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/log.py", line 193, in log_wrapper     f_result = func(*args, **kwds)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 447, in _compose_email  message = message.format(otp=otp, serial=serial)
KeyError: u'user'

It’s not entirely clear from the docs if I should be using {} or <> as keyword placeholders in the template, but it seems to be complaining about USER, even though USER is listed as a valid keyword. So I’m at a loss.

I think the documentation is very clear:
https://privacyidea.readthedocs.io/en/latest/policies/authentication.html#emailtext

Reread what user actually means and check if the user object really has the attribute you are referring to.

Docs say {user} is “the given name of the token owner”. My resolver is LDAP. Does an AD source support a literal “user” attribute? No, but it does support “the given name”. There is also a {givenname} substitution with the exact same definition as {user}, and this one would seem to be more appropriate for AD (where givenName maps to the First Name attribute).

Sorry, Cornelius, I guess I’m just stupid. This would appear to have nothing to do with user attributes, AD/LDAP, etc.

I tried something simple using the user-agnostic {date} and {time} tags within an HTML message template. If I use angle brackets <date> – such as works perfectly for <otp> – I get a successful email with no substitutions (because the tags are treated like non-functional HTML entities). If I use curly braces {} – whether alone, bound by angles, or bounding an angled tag – the GUI throws an error during substitution and no email is received.

I’m literally using keywords “date” and “time”. Is there a different incantation I should use, like u’date or ???

Basically you can use all these tags in curly brackes:

  • username
  • client_ip
  • surname
  • recipient_givenname
  • time
  • date
  • user
  • registrationcode
  • serial
  • givenname
  • googleurl_value
  • userrealm
  • realm
  • tokentype
  • url
  • admin
  • recipient_surname
  • ua_string
  • action
  • ua_browser

Some of the tags may be empty and some may not be sensible in this situation.

The question remains how your template looks like.

Instead of using a file with a full blown html template you might at first try a simple template in the policy like:

Hi, your OTP is <otp>.

(I am not sure, if the tag {otp} would work . <otp> will)

Note: Previously we only used the tags <otp> and <serial> tags. We switched to using python format strings with the curly brackets like {serial}. It coul dhowever be, that the transition is not complete and we might have missed the otp.

Checked again. We did not miss it. You can use <otp> (old format) and {otp} (new style).

Yup, confirmed the {otp}. Here is my simple-minded HTML template.

<p>The One-Time Password generated is: {otp}</p>

<pre>
Time: <time>
Date: <date>
IP: <client_ip>
Agent: <ua_browser> <ua_string>
</pre>

If I change <time> to {time} – or any of the others – the Python substitution process throws an error as below and the GUI immediately fails the login with no C-R followup.

[2019-09-17 00:20:18,807][7940][140392997590784][WARNING][privacyidea.lib.tokens.emailtoken:294] The PIN was correct, but the EMail could not be sent: KeyError(u'time',)
[2019-09-17 00:20:18,812][7940][140392997590784][DEBUG][privacyidea.lib.tokens.emailtoken:295] Traceback (most recent call last):
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 289, in create_challenge
    mimetype=mimetype)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/log.py", line 193, in log_wrapper
    f_result = func(*args, **kwds)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 447, in _compose_email
    message = message.format(otp=otp, serial=serial)
KeyError: u'time'

[2019-09-17 00:20:18,812][7940][140392997590784][DEBUG][privacyidea.lib.tokens.emailtoken:295] Traceback (most recent call last):
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 289, in create_challenge
    mimetype=mimetype)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/log.py", line 193, in log_wrapper
    f_result = func(*args, **kwds)
  File "/opt/privacyidea/local/lib/python2.7/site-packages/privacyidea/lib/tokens/emailtoken.py", line 447, in _compose_email
    message = message.format(otp=otp, serial=serial)
KeyError: u'time'

I’m currently running DEBUG level and that’s all it tells me. Any other areas I can look?

You mentioned in another thread that You are using 3.0.2. Unfortunately these extended tags are available in the current community release 3.1.
In 3.0.2 only {otp} and {serial} work.

1 Like

OMG thank you! I thought I was going crazy. Docs say “starting with 2.20 you can use {challenge}”, but it doesn’t say “starting with 3.1 you can use these other tags”. Thought I was safe. Thanks again.

I have placed a template file in /etc/privacyidea/ folder with emailtemplate.html name. but its not reflecting in the OTP mail. what i am doing wrong?

Hello @Gopal_krish

welcome to the community.
Noone can know, except you.
You really need to provide information!

Hi @cornelinux
I simply created a emailtemplate.html file in /etc/privacyidea folder with sample html designs
and restarted the server too.
this is what i have done. is there any thing stil i need to configure to make this template effective

Are you kidding me? You do not tell where you want to use emails, like in notification handlers, email tokens…
Yes, you need to configure. Do you think privacyidea will look into an arbitrary directory and simply use any file that is located there?
Read the complete site https://privacyidea.readthedocs.io
Think about what you actually want to do!
Think about what you logically need to do!
Then configure it accordingly!
If it does not work out, take some time of yours! out of respect for the time other people!
(Investing at least two to 8 hours of your time into this is I think a good rule of thumb!)

@cornelinux I read the docs i could see the pi.cfg file with some default configs. but for emailtext i could see about file path only. I could not find where to change in the docs. could you help me on that “changing OTP mail template”

Please read the part here: