[MERGE] trunk-merge_signup_resetpw-rco (merge auth_reset_password into auth_signup)

bzr revid: rco@openerp.com-20121204093535-4adcvecnozkbtbyj
This commit is contained in:
Raphael Collet 2012-12-04 10:35:35 +01:00
commit bf2a3109ee
25 changed files with 165 additions and 801 deletions

View File

@ -1,23 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
import controllers
import res_users

View File

@ -1,43 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
{
'name': 'Reset Password',
'description': """
Reset Password
==============
Allow users to reset their password from the login page.
Allow administrator to click a button to send a "Reset Password" request to a user.
""",
'author': 'OpenERP SA',
'version': '1.0',
'category': 'Authentication',
'website': 'http://www.openerp.com',
'installable': True,
'depends': ['auth_signup', 'email_template'],
'data': [
'auth_reset_password.xml',
'res_users_view.xml',
],
'js': ['static/src/js/reset_password.js'],
'qweb': ['static/src/xml/reset_password.xml'],
}

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- Email template for reset password -->
<record id="reset_password_email" model="email.template">
<field name="name">Reset Password</field>
<field name="model_id" ref="base.model_res_users"/>
<field name="email_from"><![CDATA[${object.company_id.name} <${object.company_id.email}>]]></field>
<field name="email_to">${object.email}</field>
<field name="subject">Password reset</field>
<field name="body_html"><![CDATA[
<p>A password reset was requested for the OpenERP account linked to this email.</p>
<p>You may change your password following <a href="${object.signup_url}">this link</a>.</p>
<p>Note: If you did not ask for a password reset, you can safely ignore this email.</p>]]></field>
</record>
</data>
</openerp>

View File

@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
import main
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,52 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
import logging
import werkzeug
import openerp
from openerp import SUPERUSER_ID
from openerp.modules.registry import RegistryManager
_logger = logging.getLogger(__name__)
class Controller(openerp.addons.web.http.Controller):
_cp_path = '/auth_reset_password'
@openerp.addons.web.http.httprequest
def reset_password(self, req, dbname, login):
""" retrieve user, and perform reset password """
url = '/'
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
try:
res_users = registry.get('res.users')
res_users.reset_password(cr, SUPERUSER_ID, login)
cr.commit()
message = 'An email has been sent with credentials to reset your password'
except Exception as e:
# signup error
_logger.exception('error when resetting password')
message = e.message
url = "/#action=login&error_message=%s" % werkzeug.urls.url_quote(message)
return werkzeug.utils.redirect(url)
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,70 +0,0 @@
# Arabic translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-12-01 10:40+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr ""
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr ""

View File

@ -1,65 +0,0 @@
# Translation of OpenERP Server.
# This file contains the translation of the following modules:
# * auth_reset_password
#
msgid ""
msgstr ""
"Project-Id-Version: OpenERP Server 7.0alpha\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-12-03 16:03+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid "\n"
"<p>A password reset was requested for the OpenERP account linked to this email.</p>\n"
"\n"
"<p>You may change your password following <a href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this email.</p>"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr ""
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr ""

View File

@ -1,70 +0,0 @@
# Italian translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-11-28 19:58+0000\n"
"Last-Translator: Davide Corio - agilebg.com <davide.corio@agilebg.com>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr "Utenti"
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr "Reimposta password"
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr "Ripristino password"
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr "Reimposta Password"

View File

@ -1,70 +0,0 @@
# Dutch translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-11-29 15:12+0000\n"
"Last-Translator: Erwin van der Ploeg (Endian Solutions) <Unknown>\n"
"Language-Team: Dutch <nl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr "Gebruikers"
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr "Reset wachtwoord"
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr "Reset wachtwoord"
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr "Stel wachtwoord opnieuw in"

View File

@ -1,70 +0,0 @@
# Russian translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-11-30 19:40+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Russian <ru@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr ""
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr ""
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr ""

View File

@ -1,79 +0,0 @@
# Turkish translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-11-27 22:15+0000\n"
"Last-Translator: Ahmet Altınışık <Unknown>\n"
"Language-Team: Turkish <tr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
"\n"
"<p>Bu epostayla ilişkili OpenERP hesabı için bir parola sıfırlama isteği "
"istendi.</p>\n"
"\n"
"<p>Şifrenizi şu adresten değiştirebilirsiniz. <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Not: Eğer bu parola değiştirme isteğini siz yapmadıysanız bu mesajı "
"görmezden gelebilirsiniz. </p>"
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr "Kullanıcılar"
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr "Parolayı sıfırla"
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr "Parola sıfırlandı"
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr "Parolayı Sıfırla"

View File

@ -1,74 +0,0 @@
# Chinese (Simplified) translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-03 16:03+0000\n"
"PO-Revision-Date: 2012-11-28 07:14+0000\n"
"Last-Translator: ccdos <ccdos@163.com>\n"
"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2012-12-04 05:55+0000\n"
"X-Generator: Launchpad (build 16335)\n"
#. module: auth_reset_password
#: model:email.template,body_html:auth_reset_password.reset_password_email
msgid ""
"\n"
"<p>A password reset was requested for the OpenERP account linked to this "
"email.</p>\n"
"\n"
"<p>You may change your password following <a "
"href=\"${object.signup_url}\">this link</a>.</p>\n"
"\n"
"<p>Note: If you did not ask for a password reset, you can safely ignore this "
"email.</p>"
msgstr ""
"\n"
"一个关联到这个Email地址的Openerp帐号请求复位密码。\n"
"你可以修改你的密码通过下面这个链接 <a href=\"${object.signup_url}\">。\n"
"提醒:如果你没请求复位密码,请忽略这封邮件。"
#. module: auth_reset_password
#: view:res.users:0
msgid "Send a special url by email to make the user (re)set their password."
msgstr ""
#. module: auth_reset_password
#: code:addons/auth_reset_password/res_users.py:59
#, python-format
msgid "Cannot send email: user has no email address."
msgstr ""
#. module: auth_reset_password
#: model:ir.model,name:auth_reset_password.model_res_users
msgid "Users"
msgstr "用户"
#. module: auth_reset_password
#: view:res.users:0
msgid "{}"
msgstr ""
#. module: auth_reset_password
#. openerp-web
#: code:addons/auth_reset_password/static/src/xml/reset_password.xml:7
#, python-format
msgid "Reset password"
msgstr "重设密码"
#. module: auth_reset_password
#: model:email.template,subject:auth_reset_password.reset_password_email
msgid "Password reset"
msgstr "重置密码"
#. module: auth_reset_password
#: view:res.users:0
msgid "Reset Password"
msgstr "重置密码"

View File

@ -1,62 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2012-today OpenERP SA (<http://www.openerp.com>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
from openerp.osv import osv, fields
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.translate import _
from datetime import datetime, timedelta
def now(**kwargs):
dt = datetime.now() + timedelta(**kwargs)
return dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
class res_users(osv.osv):
_inherit = 'res.users'
def reset_password(self, cr, uid, login, context=None):
""" retrieve the user corresponding to login (login or email),
and reset their password
"""
user_ids = self.search(cr, uid, [('login', '=', login)], context=context)
if not user_ids:
user_ids = self.search(cr, uid, [('email', '=', login)], context=context)
if len(user_ids) != 1:
raise Exception('Reset password: invalid username or email')
return self.action_reset_password(cr, uid, user_ids, context=context)
def action_reset_password(self, cr, uid, ids, context=None):
""" create signup token for each user, and send their signup url by email """
# prepare reset password signup
res_partner = self.pool.get('res.partner')
partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context)]
res_partner.signup_prepare(cr, uid, partner_ids, expiration=now(days=+1), context=context)
# send email to users with their signup url
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_reset_password', 'reset_password_email')
assert template._name == 'email.template'
for user in self.browse(cr, uid, ids, context):
if not user.email:
raise osv.except_osv(_("Cannot send email: user has no email address."), user.name)
self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, context=context)
return True

View File

@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="res_users_form_view" model="ir.ui.view">
<field name="name">user.form.reset_password</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<!-- Reset Password button -->
<xpath expr="//sheet/*[1]" position="before">
<div class="oe_right oe_button_box">
<button string="Reset Password" type="object" name="action_reset_password"
help="Send a special url by email to make the user (re)set their password."/>
</div>
</xpath>
<!-- password is never required; one can use Reset Password -->
<field name="new_password" position="attributes">
<attribute name="attrs">{}</attribute>
</field>
</field>
</record>
</data>
</openerp>

View File

@ -1,30 +0,0 @@
openerp.auth_reset_password = function(instance) {
var _t = instance.web._t;
instance.web.Login.include({
start: function() {
this.$('a.oe_reset_password').click(this.do_reset_password);
return this._super();
},
do_reset_password: function(ev) {
if (ev) {
ev.preventDefault();
}
var db = this.$("form [name=db]").val();
var login = this.$("form input[name=login]").val();
if (!db) {
this.do_warn("Login", "No database selected !");
return false;
} else if (!login) {
this.do_warn("Login", "Please enter a username or email address.")
return false;
}
var params = {
dbname : db,
login: login,
};
var url = "/auth_reset_password/reset_password?" + $.param(params);
window.location = url;
}
});
};

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- vim:fdl=1: -->
<templates id="template" xml:space="preserve">
<t t-extend="Login">
<t t-jquery="form ul:first li:last" t-operation="after">
<li><a class="oe_reset_password" href="#">Reset password</a></li>
</t>
</t>
</templates>

View File

@ -22,15 +22,18 @@
{
'name': 'Signup',
'description': """
Allow users to sign up.
=======================
Allow users to sign up and reset their password
===============================================
""",
'author': 'OpenERP SA',
'version': '1.0',
'category': 'Authentication',
'website': 'http://www.openerp.com',
'installable': True,
'depends': ['base_setup'],
'depends': [
'base_setup',
'email_template',
],
'data': [
'auth_signup_data.xml',
'res_config.xml',

View File

@ -18,5 +18,20 @@
<field name="value" ref="default_template_user"/>
</record>
<!-- Email template for reset password -->
<record id="reset_password_email" model="email.template">
<field name="name">Reset Password</field>
<field name="model_id" ref="base.model_res_users"/>
<field name="email_from"><![CDATA[${object.company_id.name} <${object.company_id.email}>]]></field>
<field name="email_to">${object.email}</field>
<field name="subject">Password reset</field>
<field name="body_html"><![CDATA[
<p>A password reset was requested for the OpenERP account linked to this email.</p>
<p>You may change your password by following <a href="${object.signup_url}">this link</a>.</p>
<p>Note: If you do not expect this, you can safely ignore this email.</p>]]></field>
</record>
</data>
</openerp>

View File

@ -19,10 +19,12 @@
#
##############################################################################
import logging
import urllib
import werkzeug
import openerp
from openerp.modules.registry import RegistryManager
from ..res_users import SignupError
_logger = logging.getLogger(__name__)
@ -30,6 +32,18 @@ _logger = logging.getLogger(__name__)
class Controller(openerp.addons.web.http.Controller):
_cp_path = '/auth_signup'
@openerp.addons.web.http.jsonrequest
def get_config(self, req, dbname):
""" retrieve the module config (which features are enabled) for the login page """
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
icp = registry.get('ir.config_parameter')
config = {
'signup': icp.get_param(cr, openerp.SUPERUSER_ID, 'auth_signup.allow_uninvited') == 'True',
'reset_password': icp.get_param(cr, openerp.SUPERUSER_ID, 'auth_signup.reset_password') == 'True',
}
return config
@openerp.addons.web.http.jsonrequest
def retrieve(self, req, dbname, token):
""" retrieve the user info (name, login or email) corresponding to a signup token """
@ -56,4 +70,21 @@ class Controller(openerp.addons.web.http.Controller):
cr.commit()
return {}
@openerp.addons.web.http.httprequest
def reset_password(self, req, dbname, login):
""" retrieve user, and perform reset password """
registry = RegistryManager.get(dbname)
with registry.cursor() as cr:
try:
res_users = registry.get('res.users')
res_users.reset_password(cr, openerp.SUPERUSER_ID, login)
cr.commit()
message = 'An email has been sent with credentials to reset your password'
except Exception as e:
# signup error
_logger.exception('error when resetting password')
message = e.message
params = [('action', 'login'), ('error_message', message)]
return werkzeug.utils.redirect("/#" + urllib.urlencode(params))
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -26,14 +26,19 @@ class base_config_settings(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
'auth_signup_uninvited': fields.boolean('Allow external users to sign up', help="If unchecked, only invited users may sign up"),
'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup'),
'auth_signup_reset_password': fields.boolean('Enable password reset from Login page',
help="This allows users to trigger a password reset from the Login page."),
'auth_signup_uninvited': fields.boolean('Allow external users to sign up',
help="If unchecked, only invited users may sign up."),
'auth_signup_template_user_id': fields.many2one('res.users',
string='Template user for new users created through signup'),
}
def get_default_auth_signup_template_user_id(self, cr, uid, fields, context=None):
icp = self.pool.get('ir.config_parameter')
# we use safe_eval on the result, since the value of the parameter is a nonempty string
return {
'auth_signup_reset_password': safe_eval(icp.get_param(cr, uid, 'auth_signup.reset_password', 'False')),
'auth_signup_uninvited': safe_eval(icp.get_param(cr, uid, 'auth_signup.allow_uninvited', 'False')),
'auth_signup_template_user_id': safe_eval(icp.get_param(cr, uid, 'auth_signup.template_user_id', 'False')),
}
@ -42,5 +47,6 @@ class base_config_settings(osv.TransientModel):
config = self.browse(cr, uid, ids[0], context=context)
icp = self.pool.get('ir.config_parameter')
# we store the repr of the values, since the value of the parameter is a required string
icp.set_param(cr, uid, 'auth_signup.reset_password', repr(config.auth_signup_reset_password))
icp.set_param(cr, uid, 'auth_signup.allow_uninvited', repr(config.auth_signup_uninvited))
icp.set_param(cr, uid, 'auth_signup.template_user_id', repr(config.auth_signup_template_user_id.id))

View File

@ -8,6 +8,10 @@
<field name="inherit_id" ref="base_setup.view_general_configuration"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='module_auth_anonymous']/.." position="after">
<div>
<field name="auth_signup_reset_password" class="oe_inline"/>
<label for="auth_signup_reset_password"/>
</div>
<div>
<field name="auth_signup_uninvited" class="oe_inline"/>
<label for="auth_signup_uninvited"/>

View File

@ -18,14 +18,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
from datetime import datetime, timedelta
import random
import time
import urllib
import urlparse
from openerp.osv import osv, fields
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.safe_eval import safe_eval
from openerp.tools.translate import _
class SignupError(Exception):
pass
@ -33,10 +34,12 @@ class SignupError(Exception):
def random_token():
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
return ''.join(random.choice(chars) for _ in xrange(20))
return ''.join(random.choice(chars) for i in xrange(20))
def now(**kwargs):
dt = datetime.now() + timedelta(**kwargs)
return dt.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
def now():
return time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
class res_partner(osv.Model):
_inherit = 'res.partner'
@ -58,7 +61,7 @@ class res_partner(osv.Model):
# when required, make sure the partner has a valid signup token
if context and context.get('signup_valid') and not partner.user_ids:
self.signup_prepare(cr, uid, [partner.id], context=context)
action_template = None
params = {
'action': urllib.quote(action),
@ -218,3 +221,39 @@ class res_users(osv.Model):
# create a copy of the template user (attached to a specific partner_id if given)
values['active'] = True
return self.copy(cr, uid, template_user_id, values, context=context)
def reset_password(self, cr, uid, login, context=None):
""" retrieve the user corresponding to login (login or email),
and reset their password
"""
user_ids = self.search(cr, uid, [('login', '=', login)], context=context)
if not user_ids:
user_ids = self.search(cr, uid, [('email', '=', login)], context=context)
if len(user_ids) != 1:
raise Exception('Reset password: invalid username or email')
return self.action_reset_password(cr, uid, user_ids, context=context)
def action_reset_password(self, cr, uid, ids, context=None):
""" create signup token for each user, and send their signup url by email """
# prepare reset password signup
res_partner = self.pool.get('res.partner')
partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context)]
res_partner.signup_prepare(cr, uid, partner_ids, expiration=now(days=+1), context=context)
# send email to users with their signup url
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_signup', 'reset_password_email')
assert template._name == 'email.template'
for user in self.browse(cr, uid, ids, context):
if not user.email:
raise osv.except_osv(_("Cannot send email: user has no email address."), user.name)
self.pool.get('email.template').send_mail(cr, uid, template.id, user.id, context=context)
return True
def create(self, cr, uid, values, context=None):
# overridden to automatically invite user to sign up
user_id = super(res_users, self).create(cr, uid, values, context=context)
user = self.browse(cr, uid, user_id, context=context)
if user.email:
user.action_reset_password()
return user_id

View File

@ -7,11 +7,23 @@
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<!-- add state field in header -->
<xpath expr="//sheet" position="before">
<header>
<field name="state" widget="statusbar"/>
</header>
</xpath>
<!-- add Reset Password button -->
<xpath expr="//sheet/*[1]" position="before">
<div class="oe_right oe_button_box">
<button string="Reset Password" type="object" name="action_reset_password"
help="Send an email to the user to (re)set their password."/>
</div>
</xpath>
<!-- hide field set_password -->
<field name="new_password" position="replace">
<field name="new_password" groups="base.group_no_one"/>
</field>
</field>
</record>

View File

@ -43,8 +43,28 @@ openerp.auth_signup = function(instance) {
.fail(self.on_token_failed)
});
}
// bind reset password link
this.$('a.oe_signup_reset_password').click(this.do_reset_password);
// make signup link and reset password link visible only when enabled
this.$('a.oe_signup_signup').hide();
this.$('a.oe_signup_reset_password').hide();
if (this.params.db) {
this.rpc("/auth_signup/get_config", {dbname: self.params.db})
.done(function(result) {
if (result.signup) {
self.$('a.oe_signup_signup').show();
}
if (result.reset_password) {
self.$('a.oe_signup_reset_password').show();
}
});
}
return d;
},
on_token_loaded: function(result) {
// select the right the database
this.selected_db = result.db;
@ -66,6 +86,7 @@ openerp.auth_signup = function(instance) {
this.$("form input[name=login]").val(result.login || "");
}
},
on_token_failed: function(result, ev) {
if (ev) {
ev.preventDefault();
@ -74,6 +95,7 @@ openerp.auth_signup = function(instance) {
delete this.params.db;
delete this.params.token;
},
on_submit: function(ev) {
if (ev) {
ev.preventDefault();
@ -124,6 +146,26 @@ openerp.auth_signup = function(instance) {
this._super(ev);
}
},
});
do_reset_password: function(ev) {
if (ev) {
ev.preventDefault();
}
var db = this.$("form [name=db]").val();
var login = this.$("form input[name=login]").val();
if (!db) {
this.do_warn("Login", "No database selected !");
return false;
} else if (!login) {
this.do_warn("Login", "Please enter a username or email address.")
return false;
}
var params = {
dbname : db,
login: login,
};
var url = "/auth_signup/reset_password?" + $.param(params);
window.location = url;
},
});
};

View File

@ -22,6 +22,7 @@
<button class="oe_signup_show" name="submit">Sign up</button>
<a class="oe_signup_hide oe_signup_signup" href="#">Sign Up</a>
<a class="oe_signup_show oe_signup_back" href="#">Back to Login</a>
<a class="oe_signup_reset_password" href="#">Reset password</a>
</li>
</t>
</t>