[ADD] auth_signup: merge in functionality of auth_reset_password
bzr revid: rco@openerp.com-20121203144424-39wrr5z78smswox2
This commit is contained in:
parent
772a721d85
commit
41ceffd52b
|
@ -22,15 +22,18 @@
|
||||||
{
|
{
|
||||||
'name': 'Signup',
|
'name': 'Signup',
|
||||||
'description': """
|
'description': """
|
||||||
Allow users to sign up.
|
Allow users to sign up and reset their password
|
||||||
=======================
|
===============================================
|
||||||
""",
|
""",
|
||||||
'author': 'OpenERP SA',
|
'author': 'OpenERP SA',
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
'category': 'Authentication',
|
'category': 'Authentication',
|
||||||
'website': 'http://www.openerp.com',
|
'website': 'http://www.openerp.com',
|
||||||
'installable': True,
|
'installable': True,
|
||||||
'depends': ['base_setup'],
|
'depends': [
|
||||||
|
'base_setup',
|
||||||
|
'email_template',
|
||||||
|
],
|
||||||
'data': [
|
'data': [
|
||||||
'auth_signup_data.xml',
|
'auth_signup_data.xml',
|
||||||
'res_config.xml',
|
'res_config.xml',
|
||||||
|
|
|
@ -18,5 +18,20 @@
|
||||||
<field name="value" ref="default_template_user"/>
|
<field name="value" ref="default_template_user"/>
|
||||||
</record>
|
</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>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import logging
|
import logging
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
import werkzeug
|
||||||
|
|
||||||
import openerp
|
import openerp
|
||||||
from openerp.modules.registry import RegistryManager
|
from openerp.modules.registry import RegistryManager
|
||||||
|
|
||||||
from ..res_users import SignupError
|
from ..res_users import SignupError
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
@ -56,4 +58,21 @@ class Controller(openerp.addons.web.http.Controller):
|
||||||
cr.commit()
|
cr.commit()
|
||||||
return {}
|
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:
|
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
from datetime import datetime, timedelta
|
||||||
import random
|
import random
|
||||||
import time
|
|
||||||
import urllib
|
import urllib
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
from openerp.osv import osv, fields
|
from openerp.osv import osv, fields
|
||||||
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
from openerp.tools.safe_eval import safe_eval
|
from openerp.tools.safe_eval import safe_eval
|
||||||
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
class SignupError(Exception):
|
class SignupError(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -33,10 +34,12 @@ class SignupError(Exception):
|
||||||
def random_token():
|
def random_token():
|
||||||
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
|
# the token has an entropy of about 120 bits (6 bits/char * 20 chars)
|
||||||
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
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):
|
class res_partner(osv.Model):
|
||||||
_inherit = 'res.partner'
|
_inherit = 'res.partner'
|
||||||
|
@ -218,3 +221,31 @@ class res_users(osv.Model):
|
||||||
# create a copy of the template user (attached to a specific partner_id if given)
|
# create a copy of the template user (attached to a specific partner_id if given)
|
||||||
values['active'] = True
|
values['active'] = True
|
||||||
return self.copy(cr, uid, template_user_id, values, context=context)
|
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
|
||||||
|
|
|
@ -7,11 +7,23 @@
|
||||||
<field name="model">res.users</field>
|
<field name="model">res.users</field>
|
||||||
<field name="inherit_id" ref="base.view_users_form"/>
|
<field name="inherit_id" ref="base.view_users_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
|
<!-- add state field in header -->
|
||||||
<xpath expr="//sheet" position="before">
|
<xpath expr="//sheet" position="before">
|
||||||
<header>
|
<header>
|
||||||
<field name="state" widget="statusbar"/>
|
<field name="state" widget="statusbar"/>
|
||||||
</header>
|
</header>
|
||||||
</xpath>
|
</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>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,13 @@ openerp.auth_signup = function(instance) {
|
||||||
.fail(self.on_token_failed)
|
.fail(self.on_token_failed)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind reset password link
|
||||||
|
this.$('a.oe_reset_password').click(this.do_reset_password);
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
},
|
},
|
||||||
|
|
||||||
on_token_loaded: function(result) {
|
on_token_loaded: function(result) {
|
||||||
// select the right the database
|
// select the right the database
|
||||||
this.selected_db = result.db;
|
this.selected_db = result.db;
|
||||||
|
@ -66,6 +71,7 @@ openerp.auth_signup = function(instance) {
|
||||||
this.$("form input[name=login]").val(result.login || "");
|
this.$("form input[name=login]").val(result.login || "");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
on_token_failed: function(result, ev) {
|
on_token_failed: function(result, ev) {
|
||||||
if (ev) {
|
if (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -74,6 +80,7 @@ openerp.auth_signup = function(instance) {
|
||||||
delete this.params.db;
|
delete this.params.db;
|
||||||
delete this.params.token;
|
delete this.params.token;
|
||||||
},
|
},
|
||||||
|
|
||||||
on_submit: function(ev) {
|
on_submit: function(ev) {
|
||||||
if (ev) {
|
if (ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
|
@ -124,6 +131,26 @@ openerp.auth_signup = function(instance) {
|
||||||
this._super(ev);
|
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;
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
<a class="oe_signup_show oe_signup_back" href="#">Back to Login</a>
|
<a class="oe_signup_show oe_signup_back" href="#">Back to Login</a>
|
||||||
</li>
|
</li>
|
||||||
</t>
|
</t>
|
||||||
|
<t t-jquery="form ul:first li:last" t-operation="after">
|
||||||
|
<li><a class="oe_reset_password" href="#">Reset password</a></li>
|
||||||
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
</templates>
|
</templates>
|
||||||
|
|
Loading…
Reference in New Issue