summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Beguin <dbe@odoo.com>2019-02-20 16:54:36 +0000
committerDavid Beguin <dbe@odoo.com>2019-03-15 14:58:28 +0000
commitfb40c6bf6018f7f208201e1d4a4d413fd2ce3080 (patch)
treed6df1ec5f2e7aca08311a51fad7f2ab3162a6806
parentbbedcdb19054527940fb040a0d4f22115d5be265 (diff)
[IMP] website(_profile,_forum,_slides): move validation email to profile and use in forum and elearning
Email validation was necessary on the forum to be able to begin to use the forum (ask or answer questions, vote, etc..) As the new elearning also uses karma since 705376a982d64fb41800f148a167ef0fc28ce4c6, the email validation is now also necessary in the eLearning platform. This is why this commit is moving the email validation process to website_profile and extend website_slides (eLearning) and website_forum to use this feature. In function of where the user asked to send him the validation email, the user is redirected on the forum or on the elearning when he clicks on 'Validate my account' in the received 'email validation' email. Task ID : 1943788 PR #31321
-rw-r--r--addons/website_forum/controllers/main.py37
-rw-r--r--addons/website_forum/data/forum_data.xml102
-rw-r--r--addons/website_forum/models/forum.py10
-rw-r--r--addons/website_forum/models/res_users.py51
-rw-r--r--addons/website_forum/static/src/js/website_forum.js30
-rw-r--r--addons/website_forum/views/website_forum.xml22
-rw-r--r--addons/website_profile/__manifest__.py1
-rw-r--r--addons/website_profile/controllers/main.py28
-rw-r--r--addons/website_profile/data/profile_data.xml106
-rw-r--r--addons/website_profile/models/__init__.py1
-rw-r--r--addons/website_profile/models/res_users.py58
-rw-r--r--addons/website_profile/static/src/js/website_profile.js47
-rw-r--r--addons/website_profile/views/website_profile.xml39
-rw-r--r--addons/website_slides/controllers/main.py14
-rw-r--r--addons/website_slides/views/website_slides_templates_homepage.xml16
15 files changed, 321 insertions, 241 deletions
diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py
index f31b59e430f..ed2cb30df2e 100644
--- a/addons/website_forum/controllers/main.py
+++ b/addons/website_forum/controllers/main.py
@@ -3,6 +3,7 @@
import json
import lxml
import requests
+import logging
import werkzeug.exceptions
import werkzeug.urls
import werkzeug.wrappers
@@ -15,6 +16,8 @@ from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.addons.website_profile.controllers.main import WebsiteProfile
from odoo.http import request
+_logger = logging.getLogger(__name__)
+
class WebsiteForum(WebsiteProfile):
_post_per_page = 10
@@ -26,8 +29,6 @@ class WebsiteForum(WebsiteProfile):
values.update({
'header': kwargs.get('header', dict()),
'searches': kwargs.get('searches', dict()),
- 'validation_email_sent': request.session.get('validation_email_sent', False),
- 'validation_email_done': request.session.get('validation_email_done', False),
})
if kwargs.get('forum'):
values['forum'] = kwargs.get('forum')
@@ -37,32 +38,21 @@ class WebsiteForum(WebsiteProfile):
# User and validation
# --------------------------------------------------
-
+ # TODO DBE : Those 3 are deprecated. To remove in v13.
@http.route('/forum/send_validation_email', type='json', auth='user', website=True)
- def send_validation_email(self, forum_id=None, **kwargs):
- if request.env.uid != request.website.user_id.id:
- request.env.user._send_forum_validation_email(forum_id=forum_id)
- request.session['validation_email_sent'] = True
- return True
+ def send_forum_validation_email(self, forum_id=None, **kwargs):
+ _logger.warning("The method send_forum_validation_email() is deprecated and should be removed in v13.")
+ return self.send_forum_validation_email(forum_id=forum_id, **kwargs)
@http.route('/forum/validate_email', type='http', auth='public', website=True, sitemap=False)
- def validate_email(self, token, id, email, forum_id=None, **kwargs):
- if forum_id:
- try:
- forum_id = int(forum_id)
- except ValueError:
- forum_id = None
- done = request.env['res.users'].sudo().browse(int(id)).process_forum_validation_token(token, email, forum_id=forum_id)[0]
- if done:
- request.session['validation_email_done'] = True
- if forum_id:
- return request.redirect("/forum/%s" % int(forum_id))
- return request.redirect('/forum')
+ def forum_validate_email(self, token, user_id, email, forum_id=None, **kwargs):
+ _logger.warning("The method forum_validate_email() is deprecated and should be removed in v13.")
+ return self.forum_validate_email(token=token, user_id=user_id, email=email, forum_id=forum_id, **kwargs)
@http.route('/forum/validate_email/close', type='json', auth='public', website=True)
- def validate_email_done(self):
- request.session['validation_email_done'] = False
- return True
+ def forum_validate_email_done(self, **kwargs):
+ _logger.warning("The method forum_validate_email_done() is deprecated and should be removed in v13.")
+ return self.validate_email_done(**kwargs)
# Forum
# --------------------------------------------------
@@ -550,6 +540,7 @@ class WebsiteForum(WebsiteProfile):
# Profile
# -----------------------------------
+
@http.route(['/forum/<model("forum.forum"):forum>/user/<int:user_id>'], type='http', auth="public", website=True)
def view_user_forum_profile(self, forum, user_id, **post):
return werkzeug.utils.redirect('/profile/user/' + str(user_id) + '?forum_id=' + str(forum.id))
diff --git a/addons/website_forum/data/forum_data.xml b/addons/website_forum/data/forum_data.xml
index fe5fb2b8ea2..4196804495a 100644
--- a/addons/website_forum/data/forum_data.xml
+++ b/addons/website_forum/data/forum_data.xml
@@ -129,107 +129,5 @@
<field name="reason_type">offensive</field>
</record>
- <!-- Email template for email validation (for karma purpose) -->
- <record id="validation_email" model="mail.template">
- <field name="name">Forum: Email Verification</field>
- <field name="model_id" ref="base.model_res_users"/>
- <field name="subject">${object.company_id.name} Forums validation</field>
- <field name="email_from">${('&lt;%s&gt;' % (object.env.user.company_id.email or user.email)) | safe}</field>
- <field name="email_to">${object.email|safe}</field>
- <field name="body_html" type="html">
-<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
-<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
-<tbody>
- <!-- HEADER -->
- <tr>
- <td align="center" style="min-width: 590px;">
- <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
- <tr>
- <td valign="middle">
- <span style="font-size: 10px;">Your Forum</span><br/>
- <span style="font-size: 20px; font-weight: bold;">
- ${object.company_id.name} Forum validation
- </span>
- </td>
- <td valign="middle" align="right">
- <img src="/logo.png?company=${user.company_id.id}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${user.company_id.name}"/>
- </td>
- </tr>
- <tr>
- <td colspan="2" style="text-align:center;">
- <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:16px 0px 16px 0px;"/>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- <!-- CONTENT -->
- <tr>
- <td align="center" style="min-width: 590px;">
- <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
- <tr>
- <td valign="top" style="font-size: 13px;">
- <p style="margin: 0px; padding: 0px; font-size: 13px;">
- Hello ${object.name},<br /><br />
- You have been invited to validate your email in order to get access to "${object.company_id.name}" Q/A Forums.
- To validate your email, please click on the following link:
- <div style="margin: 16px 0px 16px 0px;">
- <a href="${ctx.get('token_url')}"
- style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">
- Validate my account
- </a>
- </div>
- Thanks for your participation!
- </p>
- </td>
- </tr>
- <tr>
- <td style="text-align:center;">
- <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- <!-- FOOTER -->
- <tr>
- <td align="center" style="min-width: 590px;">
- <table border="0" cellpadding="0" cellspacing="0" width="590" style=" font-family: 'Verdana Regular'; color: #454748; min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">
- <tr>
- <td valign="middle" align="left">
- ${user.company_id.name}
- </td>
- <td valign="middle" align="right" style="opacity: 0.7;">
- ${user.company_id.phone}
- % if user.company_id.email:
- | <a href="'mailto:%s' % ${user.company_id.email}" style="text-decoration:none; color: #454748;">
- ${user.company_id.email}
- </a>
- % endif
- % if user.company_id.website:
- | <a href="${user.company_id.website}" style="text-decoration:none; color: #454748;">
- ${user.company_id.website}
- </a>
- % endif
- </td>
- </tr>
- </table>
- </td>
- </tr>
-</tbody>
-</table>
-</td></tr>
-<!-- POWERED BY -->
-<tr><td align="center" style="min-width: 590px;">
- <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
- <tr><td style="text-align: center; font-size: 13px;">
- Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=forum" style="color: #875A7B;">Odoo</a>
- </td></tr>
- </table>
-</td></tr>
-</table>
- </field>
- </record>
-
</data>
</odoo>
diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py
index 68d48b8534f..4dc172a90a0 100644
--- a/addons/website_forum/models/forum.py
+++ b/addons/website_forum/models/forum.py
@@ -4,7 +4,6 @@
import logging
import math
import re
-import uuid
from datetime import datetime
from odoo.addons.gamification.models.gamification_karma_rank import KarmaError
@@ -21,15 +20,6 @@ class Forum(models.Model):
_description = 'Forum'
_inherit = ['mail.thread', 'website.seo.metadata', 'website.multi.mixin']
- @api.model_cr
- def init(self):
- """ Add forum uuid for user email validation.
-
- TDE TODO: move me somewhere else, auto_init ? """
- forum_uuids = self.env['ir.config_parameter'].search([('key', '=', 'website_forum.uuid')])
- if not forum_uuids:
- forum_uuids.set_param('website_forum.uuid', str(uuid.uuid4()))
-
@api.model
def _get_default_faq(self):
with misc.file_open('website_forum/data/forum_default_faq.html', 'r') as f:
diff --git a/addons/website_forum/models/res_users.py b/addons/website_forum/models/res_users.py
index 43791f3538c..67326175ac9 100644
--- a/addons/website_forum/models/res_users.py
+++ b/addons/website_forum/models/res_users.py
@@ -32,57 +32,6 @@ class Users(models.Model):
domain = [('parent_id', '=', False), ('state', '=', 'pending'), ('create_uid', '=', user.id)]
user.forum_waiting_posts_count = Post.search_count(domain)
- @api.model
- def _generate_forum_token(self, user_id, email):
- """Return a token for email validation. This token is valid for the day
- and is a hash based on a (secret) uuid generated by the forum module,
- the user_id, the email and currently the day (to be updated if necessary). """
- forum_uuid = self.env['ir.config_parameter'].sudo().get_param('website_forum.uuid')
- return hashlib.sha256((u'%s-%s-%s-%s' % (
- datetime.now().replace(hour=0, minute=0, second=0, microsecond=0),
- forum_uuid,
- user_id,
- email
- )).encode('utf-8')).hexdigest()
-
- @api.one
- def _send_forum_validation_email(self, forum_id=None):
- if not self.email:
- return False
- token = self._generate_forum_token(self.id, self.email)
- activation_template = self.env.ref('website_forum.validation_email')
- if activation_template:
- params = {
- 'token': token,
- 'id': self.id,
- 'email': self.email}
- if forum_id:
- params['forum_id'] = forum_id
- base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
- token_url = base_url + '/forum/validate_email?%s' % urls.url_encode(params)
- with self._cr.savepoint():
- activation_template.sudo().with_context(token_url=token_url).send_mail(
- self.id, force_send=True, raise_exception=True)
- return True
-
- @api.one
- def process_forum_validation_token(self, token, email, forum_id=None, context=None):
- validation_token = self._generate_forum_token(self.id, email)
- if token == validation_token and self.karma == 0:
- karma = 3
- forum = None
- if forum_id:
- forum = self.env['forum.forum'].browse(forum_id)
- else:
- forum_ids = self.env['forum.forum'].search([], limit=1)
- if forum_ids:
- forum = forum_ids[0]
- if forum:
- # karma gained: karma to ask a question and have 2 downvotes
- karma = forum.karma_ask + (-2 * forum.karma_gen_question_downvote)
- return self.write({'karma': karma})
- return False
-
# Wrapper for call_kw with inherits
@api.multi
def open_website_url(self):
diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js
index 613163a045a..cfca0be8454 100644
--- a/addons/website_forum/static/src/js/website_forum.js
+++ b/addons/website_forum/static/src/js/website_forum.js
@@ -6,6 +6,7 @@ var Wysiwyg = require('web_editor.wysiwyg.root');
var sAnimations = require('website.content.snippets.animation');
var session = require('web.session');
var qweb = core.qweb;
+var WebsiteProfile = require('website_profile.website_profile');
var _t = core._t;
@@ -29,8 +30,6 @@ sAnimations.registry.websiteForum = sAnimations.Class.extend({
'click .favourite_question': '_onFavoriteQuestionClick',
'click .comment_delete': '_onDeleteCommentClick',
'click .notification_close': '_onCloseNotificationClick',
- 'click .send_validation_email': '_onSendValidationEmailClick',
- 'click .validated_email_close': '_onCloseValidatedEmailClick',
'click .js_close_intro': '_onCloseIntroClick',
},
@@ -469,32 +468,6 @@ sAnimations.registry.websiteForum = sAnimations.Class.extend({
* @private
* @param {Event} ev
*/
- _onSendValidationEmailClick: function (ev) {
- ev.preventDefault();
- var $link = $(ev.currentTarget);
- this._rpc({
- route: '/forum/send_validation_email',
- params: {
- forum_id: $link.attr('forum-id'),
- },
- }).then(function (data) {
- if (data) {
- $('button.validation_email_close').click();
- }
- });
- },
- /**
- * @private
- */
- _onCloseValidatedEmailClick: function () {
- this._rpc({
- route: '/forum/validate_email/close',
- });
- },
- /**
- * @private
- * @param {Event} ev
- */
_onCloseIntroClick: function (ev) {
ev.preventDefault();
document.cookie = 'forum_welcome_message = false';
@@ -579,4 +552,5 @@ sAnimations.registry.websiteForumSpam = sAnimations.Class.extend({
});
},
});
+
});
diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml
index 482a7d9541b..1c4755f7092 100644
--- a/addons/website_forum/views/website_forum.xml
+++ b/addons/website_forum/views/website_forum.xml
@@ -52,22 +52,12 @@
<div id="wrap" t-attf-class="container #{website_forum_action}">
<div class="row">
- <div class="col o_left_forum_container mb16 mt16">
- <div t-if="not validation_email_sent and not is_public_user and user.karma == 0" class="alert alert-danger alert-dismissable" role="alert">
- <button type="button" class="close validation_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
- <div>
- <p>
- It appears your email has not been verified.
- <a class="send_validation_email" href="#" t-att-forum-id="forum.id">Click here to send a verification email allowing you to participate to the forum.</a>
- </p>
- </div>
- </div>
- <div t-if="validation_email_done" class="alert alert-success alert-dismissable" role="status">
- <button type="button" class="close validated_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
- <div>
- <p>Congratulations! Your email has just been validated. You may now participate to our forums.</p>
- </div>
- </div>
+ <div class="o_wprofile_email_validation_container mb16 mt16">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/forum/%s' % forum.id"/>
+ <t t-set="send_validation_email_message" t-value="'Click here to send a verification email allowing you to participate to the forum.'"/>
+ <t t-set="additional_validated_email_message" t-value="' You may now participate to our forums.'"/>
+ </t>
<t t-raw="0"/>
</div>
<t t-if="not is_profile_page">
diff --git a/addons/website_profile/__manifest__.py b/addons/website_profile/__manifest__.py
index 1214d3f03e8..fbb57d126fd 100644
--- a/addons/website_profile/__manifest__.py
+++ b/addons/website_profile/__manifest__.py
@@ -12,6 +12,7 @@
'gamification'
],
'data': [
+ 'data/profile_data.xml',
'views/gamification_badge_views.xml',
'views/website_profile.xml',
'security/ir.model.access.csv',
diff --git a/addons/website_profile/controllers/main.py b/addons/website_profile/controllers/main.py
index 4d0e58efbe8..b29ba2077fb 100644
--- a/addons/website_profile/controllers/main.py
+++ b/addons/website_profile/controllers/main.py
@@ -57,6 +57,8 @@ class WebsiteProfile(http.Controller):
values = {
'user': request.env.user,
'is_public_user': request.website.is_public_user(),
+ 'validation_email_sent': request.session.get('validation_email_sent', False),
+ 'validation_email_done': request.session.get('validation_email_done', False),
}
values.update(kwargs)
return values
@@ -111,8 +113,9 @@ class WebsiteProfile(http.Controller):
user = self._check_user_profile_access(user_id)
if not user:
return request.render("website_profile.private_profile")
+ values = self._prepare_user_values(**post)
params = self._prepare_user_profile_parameters(**post)
- values = self._prepare_user_profile_values(user, **params)
+ values.update(self._prepare_user_profile_values(user, **params))
return request.render("website_profile.user_profile_main", values)
# Edit Profile
@@ -234,3 +237,26 @@ class WebsiteProfile(http.Controller):
'pager': pager
}
return request.render("website_profile.users_page_main", values)
+
+ # User and validation
+ # --------------------------------------------------
+
+ @http.route('/profile/send_validation_email', type='json', auth='user', website=True)
+ def send_validation_email(self, **kwargs):
+ if request.env.uid != request.website.user_id.id:
+ request.env.user._send_profile_validation_email(**kwargs)
+ request.session['validation_email_sent'] = True
+ return True
+
+ @http.route('/profile/validate_email', type='http', auth='public', website=True, sitemap=False)
+ def validate_email(self, token, user_id, email, **kwargs):
+ done = request.env['res.users'].sudo().browse(int(user_id))._process_profile_validation_token(token, email)
+ if done:
+ request.session['validation_email_done'] = True
+ url = kwargs.get('redirect_url', '/')
+ return request.redirect(url)
+
+ @http.route('/profile/validate_email/close', type='json', auth='public', website=True)
+ def validate_email_done(self, **kwargs):
+ request.session['validation_email_done'] = False
+ return True
diff --git a/addons/website_profile/data/profile_data.xml b/addons/website_profile/data/profile_data.xml
new file mode 100644
index 00000000000..5331fa23e8e
--- /dev/null
+++ b/addons/website_profile/data/profile_data.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data noupdate="1">
+
+ <!-- Email template for email validation (for karma purpose) -->
+ <record id="validation_email" model="mail.template">
+ <field name="name">Profile: Email Verification</field>
+ <field name="model_id" ref="base.model_res_users"/>
+ <field name="subject">${object.company_id.name} Profile validation</field>
+ <field name="email_from">${('&lt;%s&gt;' % (object.env.user.company_id.email or user.email)) | safe}</field>
+ <field name="email_to">${object.email|safe}</field>
+ <field name="body_html" type="html">
+<table border="0" cellpadding="0" cellspacing="0" style="padding-top: 16px; background-color: #F1F1F1; color: #454748; width: 100%; border-collapse:separate;"><tr><td align="center">
+<table border="0" cellpadding="0" cellspacing="0" width="590" style="padding: 16px; background-color: white; color: #454748; border-collapse:separate;">
+<tbody>
+ <!-- HEADER -->
+ <tr>
+ <td align="center" style="min-width: 590px;">
+ <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
+ <tr>
+ <td valign="middle">
+ <span style="font-size: 20px; font-weight: bold;">
+ ${object.company_id.name} Profile validation
+ </span>
+ </td>
+ <td valign="middle" align="right">
+ <img src="/logo.png?company=${user.company_id.id}" style="padding: 0px; margin: 0px; height: auto; width: 80px;" alt="${user.company_id.name}"/>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align:center;">
+ <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin:16px 0px 16px 0px;"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <!-- CONTENT -->
+ <tr>
+ <td align="center" style="min-width: 590px;">
+ <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: white; padding: 0px 8px 0px 8px; border-collapse:separate;">
+ <tr>
+ <td valign="top" style="font-size: 13px;">
+ <p style="margin: 0px; padding: 0px; font-size: 13px;">
+ Hello ${object.name},<br /><br />
+ You have been invited to validate your email in order to get access to "${object.company_id.name}" website.
+ To validate your email, please click on the following link:
+ <div style="margin: 16px 0px 16px 0px;">
+ <a href="${ctx.get('token_url')}"
+ style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">
+ Validate my account
+ </a>
+ </div>
+ Thanks for your participation!
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td style="text-align:center;">
+ <hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0; margin: 16px 0px 16px 0px;"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <!-- FOOTER -->
+ <tr>
+ <td align="center" style="min-width: 590px;">
+ <table border="0" cellpadding="0" cellspacing="0" width="590" style=" font-family: 'Verdana Regular'; color: #454748; min-width: 590px; background-color: white; font-size: 11px; padding: 0px 8px 0px 8px; border-collapse:separate;">
+ <tr>
+ <td valign="middle" align="left">
+ ${user.company_id.name}
+ </td>
+ <td valign="middle" align="right" style="opacity: 0.7;">
+ ${user.company_id.phone}
+ % if user.company_id.email:
+ | <a href="'mailto:%s' % ${user.company_id.email}" style="text-decoration:none; color: #454748;">
+ ${user.company_id.email}
+ </a>
+ % endif
+ % if user.company_id.website:
+ | <a href="${user.company_id.website}" style="text-decoration:none; color: #454748;">
+ ${user.company_id.website}
+ </a>
+ % endif
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</tbody>
+</table>
+</td></tr>
+<!-- POWERED BY -->
+<tr><td align="center" style="min-width: 590px;">
+ <table border="0" cellpadding="0" cellspacing="0" width="590" style="min-width: 590px; background-color: #F1F1F1; color: #454748; padding: 8px; border-collapse:separate;">
+ <tr><td style="text-align: center; font-size: 13px;">
+ Powered by <a target="_blank" href="https://www.odoo.com?utm_source=db&amp;utm_medium=forum" style="color: #875A7B;">Odoo</a>
+ </td></tr>
+ </table>
+</td></tr>
+</table>
+ </field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/website_profile/models/__init__.py b/addons/website_profile/models/__init__.py
index c26e78d1255..e5d082ad113 100644
--- a/addons/website_profile/models/__init__.py
+++ b/addons/website_profile/models/__init__.py
@@ -3,3 +3,4 @@
from . import gamification_badge
from . import website
+from . import res_users
diff --git a/addons/website_profile/models/res_users.py b/addons/website_profile/models/res_users.py
new file mode 100644
index 00000000000..5bf49be0a78
--- /dev/null
+++ b/addons/website_profile/models/res_users.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import hashlib
+import uuid
+
+from datetime import datetime
+from werkzeug import urls
+from odoo import api, models
+
+VALIDATION_KARMA_GAIN = 3
+
+
+class Users(models.Model):
+ _inherit = 'res.users'
+
+ @api.model
+ def _generate_profile_token(self, user_id, email):
+ """Return a token for email validation. This token is valid for the day
+ and is a hash based on a (secret) uuid generated by the forum module,
+ the user_id, the email and currently the day (to be updated if necessary). """
+ profile_uuid = self.env['ir.config_parameter'].sudo().get_param('website_profile.uuid')
+ if not profile_uuid:
+ profile_uuid = str(uuid.uuid4())
+ self.env['ir.config_parameter'].sudo().set_param('website_profile.uuid', profile_uuid)
+ return hashlib.sha256((u'%s-%s-%s-%s' % (
+ datetime.now().replace(hour=0, minute=0, second=0, microsecond=0),
+ profile_uuid,
+ user_id,
+ email
+ )).encode('utf-8')).hexdigest()
+
+ def _send_profile_validation_email(self, **kwargs):
+ if not self.email:
+ return False
+ token = self._generate_profile_token(self.id, self.email)
+ activation_template = self.env.ref('website_profile.validation_email')
+ if activation_template:
+ params = {
+ 'token': token,
+ 'user_id': self.id,
+ 'email': self.email
+ }
+ params.update(kwargs)
+ base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
+ token_url = base_url + '/profile/validate_email?%s' % urls.url_encode(params)
+ with self._cr.savepoint():
+ activation_template.sudo().with_context(token_url=token_url).send_mail(
+ self.id, force_send=True, raise_exception=True)
+ return True
+
+ @api.multi
+ def _process_profile_validation_token(self, token, email):
+ self.ensure_one()
+ validation_token = self._generate_profile_token(self.id, email)
+ if token == validation_token and self.karma == 0:
+ return self.write({'karma': VALIDATION_KARMA_GAIN})
+ return False
diff --git a/addons/website_profile/static/src/js/website_profile.js b/addons/website_profile/static/src/js/website_profile.js
new file mode 100644
index 00000000000..a3cc18f53f5
--- /dev/null
+++ b/addons/website_profile/static/src/js/website_profile.js
@@ -0,0 +1,47 @@
+odoo.define('website_profile.website_profile', function (require) {
+'use strict';
+
+var sAnimations = require('website.content.snippets.animation');
+
+//TODO DBE : to change into publicWidget = require('web.public.widget'); after forward port in master
+sAnimations.registry.websiteProfile = sAnimations.Class.extend({
+ selector: '.o_wprofile_email_validation_container',
+ read_events: {
+ 'click .send_validation_email': '_onSendValidationEmailClick',
+ 'click .validated_email_close': '_onCloseValidatedEmailClick',
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+ /**
+ * @private
+ * @param {Event} ev
+ */
+ _onSendValidationEmailClick: function (ev) {
+ ev.preventDefault();
+ var self = this;
+ var $element = $(ev.currentTarget);
+ this._rpc({
+ route: '/profile/send_validation_email',
+ params: {'redirect_url': $element.data('redirect_url')},
+ }).then(function (data) {
+ if (data) {
+ self.$('button.validation_email_close').click();
+ }
+ });
+ },
+
+ /**
+ * @private
+ */
+ _onCloseValidatedEmailClick: function () {
+ this._rpc({
+ route: '/profile/validate_email/close',
+ });
+ },
+});
+
+return sAnimations.registry.websiteProfile;
+
+});
diff --git a/addons/website_profile/views/website_profile.xml b/addons/website_profile/views/website_profile.xml
index 2a108ef8906..fc9e6aae113 100644
--- a/addons/website_profile/views/website_profile.xml
+++ b/addons/website_profile/views/website_profile.xml
@@ -4,6 +4,9 @@
<xpath expr="link[last()]" position="after">
<link rel="stylesheet" type="text/scss" href="/website_profile/static/src/scss/website_profile.scss"/>
</xpath>
+ <xpath expr="script[last()]" position="after">
+ <script type="text/javascript" src="/website_profile/static/src/js/website_profile.js"/>
+ </xpath>
</template>
@@ -130,7 +133,7 @@
<div class="col-12 col-md-4 col-lg-3">
<div t-attf-class="d-flex align-items-start #{'justify-content-between' if (request.env.user == user) else 'justify-content-around' }">
<div class="o_wprofile_pict d-inline-block mb-3 mb-md-0" t-attf-style="background-image:url(/web/image/res.users/#{user.id}/image)"/>
- <a class="btn btn-primary d-inline-block d-md-none" t-if="request.env.user == user" t-attf-href="/profile/edit?url_param=#{edit_button_url_param}">
+ <a class="btn btn-primary d-inline-block d-md-none" t-if="request.env.user == user and validation_email_done" t-attf-href="/profile/edit?url_param=#{edit_button_url_param}">
<i class="fa fa-pencil mr-1"/>EDIT
</a>
</div>
@@ -139,8 +142,10 @@
<!-- ==== Header Right ==== -->
<div class="col-12 col-md-8 col-lg-9 d-flex flex-column">
<div class="d-flex justify-content-between align-items-start">
- <h1 class="o_card_people_name" t-field="user.name"/>
- <a class="btn btn-primary d-none d-md-inline-block" t-if="request.env.user == user" t-attf-href="/profile/edit?url_param=#{edit_button_url_param}">
+ <h1 class="o_card_people_name">
+ <span t-field="user.name"/><small t-if="not validation_email_done"> (not verified)</small>
+ </h1>
+ <a class="btn btn-primary d-none d-md-inline-block" t-if="request.env.user == user and validation_email_done" t-attf-href="/profile/edit?url_param=#{edit_button_url_param}">
<i class="fa fa-pencil mr-2"/>EDIT PROFILE
</a>
</div>
@@ -212,6 +217,12 @@
</ul>
<div class="tab-content py-4 o_wprofile_tabs_content mb-4" id="profile_extra_info_tabcontent">
<div role="tabpanel" class="tab-pane active" id="profile_tab_content_about">
+ <div class="o_wprofile_email_validation_container mb16 mt16">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/profile/user/%s' % user.id"/>
+ <t t-set="send_validation_email_message" t-value="'Click here to send a verification email.'"/>
+ </t>
+ </div>
<div id="profile_about_badge" class="mb32">
<h5 class="border-bottom pb-1">Badges</h5>
<t t-call="website_profile.user_badges"></t>
@@ -463,4 +474,26 @@
</ul>
</template>
+ <template id="email_validation_banner">
+ <div t-if="not validation_email_sent and not is_public_user and user.karma == 0" class="alert alert-danger alert-dismissable" role="alert">
+ <button type="button" class="close validation_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
+ <div>
+ <p>
+ It appears your email has not been verified.
+ <a class="send_validation_email" href="#" t-att-data-redirect_url="redirect_url">
+ <span t-esc="send_validation_email_message"/></a>
+ </p>
+ </div>
+ </div>
+ <div t-if="validation_email_done" class="alert alert-success alert-dismissable" role="status">
+ <button type="button" class="close validated_email_close" data-dismiss="alert" aria-label="Close">&amp;times;</button>
+ <div>
+ <p>
+ <span id="email_validated_message">Congratulations! Your email has just been validated.</span>
+ <span t-esc="additional_validated_email_message"/>
+ </p>
+ </div>
+ </div>
+ </template>
+
</data></odoo>
diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index 70137487c0c..26533550f2d 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -242,9 +242,8 @@ class WebsiteSlides(WebsiteProfile):
else:
users = None
- return request.render('website_slides.courses_home', {
- 'user': request.env.user,
- 'is_public_user': request.website.is_public_user(),
+ values = self._prepare_user_values(**post)
+ values.update({
'channels_my': channels_my,
'channels_popular': channels_popular,
'channels_newest': channels_newest,
@@ -254,6 +253,8 @@ class WebsiteSlides(WebsiteProfile):
'challenges_done': challenges_done,
})
+ return request.render('website_slides.courses_home', values)
+
@http.route('/slides/all', type='http', auth="public", website=True)
def slides_channel_all(self, slide_type=None, my=False, **post):
""" Home page displaying a list of courses displayed according to some
@@ -282,9 +283,8 @@ class WebsiteSlides(WebsiteProfile):
tag_groups = request.env['slide.channel.tag.group'].search(['&', ('tag_ids', '!=', False), ('website_published', '=', True)])
search_tags = self._extract_channel_tag_search(**post)
- return request.render('website_slides.courses_all', {
- 'user': request.env.user,
- 'is_public_user': request.website.is_public_user(),
+ values = self._prepare_user_values(**post)
+ values.update({
'channels': channels,
'tag_groups': tag_groups,
'search_term': post.get('search'),
@@ -294,6 +294,8 @@ class WebsiteSlides(WebsiteProfile):
'search_channel_tag_id': post.get('channel_tag_id'),
})
+ return request.render('website_slides.courses_all', values)
+
def _prepare_additional_channel_values(self, values, **kwargs):
return values
diff --git a/addons/website_slides/views/website_slides_templates_homepage.xml b/addons/website_slides/views/website_slides_templates_homepage.xml
index 108221a7ab0..118a42aa4ac 100644
--- a/addons/website_slides/views/website_slides_templates_homepage.xml
+++ b/addons/website_slides/views/website_slides_templates_homepage.xml
@@ -41,7 +41,15 @@
</div>
</div>
</nav>
+ <div class="o_wprofile_email_validation_container mb16 mt16">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/slides'"/>
+ <t t-set="send_validation_email_message" t-value="'Click here to send a verification email allowing you to participate to the eLearning.'"/>
+ <t t-set="additional_validated_email_message" t-value="' You may now participate to our eLearning.'"/>
+ </t>
+ </div>
</div>
+
<div class="container o_wslides_home_main">
<div class="row">
<div t-if="is_public_user" class="col-lg-3 order-3 order-lg-2">
@@ -206,6 +214,13 @@
</form>
</div>
</nav>
+ <div class="o_wprofile_email_validation_container mb16 mt16">
+ <t t-call="website_profile.email_validation_banner">
+ <t t-set="redirect_url" t-value="'/slides'"/>
+ <t t-set="send_validation_email_message" t-value="'Click here to send a verification email allowing you to participate to the eLearning.'"/>
+ <t t-set="additional_validated_email_message" t-value="' You may now participate to our eLearning.'"/>
+ </t>
+ </div>
</div>
<div class="container o_wslides_home_main pb-5">
<div t-if="search_term and not channels" class="alert alert-info mb-5">
@@ -383,5 +398,4 @@
t-att-src="'/profile/avatar/%s?field=image_medium' % user.id"
t-att-alt="user.name"/>
</template>
-
</data></odoo>