[FIX] auth_reset_password
bzr revid: chs@openerp.com-20120803170418-8qxsqgkzx3h91kz3
This commit is contained in:
parent
7c66cce877
commit
0781ec7a2a
|
@ -10,11 +10,11 @@ from openerp.osv import osv, fields
|
||||||
TWENTY_FOUR_HOURS = 24 * 60 * 60
|
TWENTY_FOUR_HOURS = 24 * 60 * 60
|
||||||
|
|
||||||
def message_sign(data, secret):
|
def message_sign(data, secret):
|
||||||
src = simplejson.dumps([data,secret], indent=None, separators=(',', ':'), sort_keys=True)
|
src = simplejson.dumps([data, secret], indent=None, separators=(',', ':'), sort_keys=True)
|
||||||
sign = hashlib.sha1(src).hexdigest()
|
sign = hashlib.sha1(src).hexdigest()
|
||||||
msg = simplejson.dumps([data,sign], indent=None, separators=(',', ':'), sort_keys=True)
|
msg = simplejson.dumps([data, sign], indent=None, separators=(',', ':'), sort_keys=True)
|
||||||
# pad message to avoid '='
|
# pad message to avoid '='
|
||||||
pad = (3-len(msg)%3)%3
|
pad = (3 - len(msg) % 3) % 3
|
||||||
msg = msg + " " * pad
|
msg = msg + " " * pad
|
||||||
msg = base64.urlsafe_b64encode(msg)
|
msg = base64.urlsafe_b64encode(msg)
|
||||||
return msg, sign
|
return msg, sign
|
||||||
|
@ -35,7 +35,7 @@ class res_users(osv.osv):
|
||||||
('email_uniq', 'UNIQUE (user_email)', 'You can not have two users with the same email!')
|
('email_uniq', 'UNIQUE (user_email)', 'You can not have two users with the same email!')
|
||||||
]
|
]
|
||||||
|
|
||||||
def _auth_reset_password_secret(self, cr, uid, ids, context=None):
|
def _auth_reset_password_secret(self, cr, uid, context=None):
|
||||||
uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
|
uuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
|
||||||
res = {
|
res = {
|
||||||
'dbname': cr.dbname,
|
'dbname': cr.dbname,
|
||||||
|
@ -44,34 +44,46 @@ class res_users(osv.osv):
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _auth_reset_password_host(self, cr, uid, ids, context=None):
|
def _auth_reset_password_host(self, cr, uid, context=None):
|
||||||
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', '')
|
return self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', '')
|
||||||
|
|
||||||
def _auth_reset_password_link(self, cr, uid, ids, context=None):
|
def _auth_reset_password_link(self, cr, uid, ids, context=None):
|
||||||
assert len(ids) == 1
|
assert len(ids) == 1
|
||||||
user = self.browse(cr, uid, ids[0], context=context)
|
host = self._auth_reset_password_host(cr, uid, context)
|
||||||
host = self._auth_reset_password_host(cr, uid, ids, context)
|
secret = self._auth_reset_password_secret(cr, uid, context)
|
||||||
secret = self._auth_reset_password_secret(cr, uid, ids, context)
|
|
||||||
msg_src = {
|
msg_src = {
|
||||||
'time' : time.time(),
|
'time': time.time(),
|
||||||
'uid' : ids[0],
|
'uid': ids[0],
|
||||||
}
|
}
|
||||||
msg, sign = message_sign(msg_src, secret)
|
msg, sign = message_sign(msg_src, secret)
|
||||||
link = urlparse.urljoin(host, '/web/webclient/home#action_id=reset_password&token=%s' % msg)
|
link = urlparse.urljoin(host, '/web/webclient/login?db=%s&login=anonymous&key=anonymous#client_action=reset_password&token=%s' % (cr.dbname, msg))
|
||||||
return link
|
return link
|
||||||
|
|
||||||
def _auth_reset_password_check_token(self, cr, uid, token, context=None):
|
def _auth_reset_password_check_token(self, cr, uid, token, context=None):
|
||||||
secret = self._auth_reset_password_secret(cr, uid, ids, context)
|
secret = self._auth_reset_password_secret(cr, uid, context)
|
||||||
data = message_check(token, secret)
|
data = message_check(token, secret)
|
||||||
if data and (time.time() - data['time'] < TWENTY_FOUR_HOURS):
|
if data and (time.time() - data['time'] < TWENTY_FOUR_HOURS):
|
||||||
return data
|
return data
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _auth_reset_password_send_email(self, cr, uid, email_to, tpl_name, res_id, context=None):
|
||||||
|
model, tpl_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_reset_password', tpl_name)
|
||||||
|
assert model == 'email.template'
|
||||||
|
|
||||||
|
msg_id = self.pool.get(model).send_mail(cr, uid, tpl_id, res_id, force_send=False, context=context)
|
||||||
|
MailMessage = self.pool.get('mail.message')
|
||||||
|
MailMessage.write(cr, uid, [msg_id], {'email_to': email_to}, context=context)
|
||||||
|
MailMessage.send(cr, uid, [msg_id], context=context)
|
||||||
|
|
||||||
def send_reset_password_request(self, cr, uid, email, context=None):
|
def send_reset_password_request(self, cr, uid, email, context=None):
|
||||||
ids = self.pool.get('res.users').search(cr, 1, [('user_email', '=', email)], context=context)
|
ids = self.pool.get('res.users').search(cr, 1, [('user_email', '=', email)], context=context)
|
||||||
if ids:
|
if ids:
|
||||||
model, template_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'auth_reset_password', 'reset_password_email')
|
self._auth_reset_password_send_email(cr, 1, email, 'reset_password_email', ids[0], context=context)
|
||||||
msg_id = self.pool.get('email.template').send_mail(cr, uid, template_id, ids[0], context=ctx)
|
return True
|
||||||
return True
|
#else:
|
||||||
|
# _m, company_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'main_company')
|
||||||
|
# self._auth_reset_password_send_email(cr, uid, email, 'email_no_user', company_id, context=context)
|
||||||
|
return False
|
||||||
|
|
||||||
class auth_reset_password(osv.TransientModel):
|
class auth_reset_password(osv.TransientModel):
|
||||||
_name = 'auth.reset_password'
|
_name = 'auth.reset_password'
|
||||||
|
@ -86,16 +98,16 @@ class auth_reset_password(osv.TransientModel):
|
||||||
'state': 'draft',
|
'state': 'draft',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def create(self, cr, uid, values, context=None):
|
def create(self, cr, uid, values, context=None):
|
||||||
# NOTE here, invalid values raises exceptions to avoid storing
|
# NOTE here, invalid values raises exceptions to avoid storing
|
||||||
# sensitive data into the database (which then are available to anyone)
|
# sensitive data into the database (which then are available to anyone)
|
||||||
|
|
||||||
if values['password'] != values['password_confirmation']:
|
pw = values.get('password')
|
||||||
|
if not pw or pw != values.get('password_confirmation'):
|
||||||
raise osv.except_osv('Error', 'Passwords missmatch')
|
raise osv.except_osv('Error', 'Passwords missmatch')
|
||||||
|
|
||||||
Users = self.pool.get('res.users')
|
Users = self.pool.get('res.users')
|
||||||
data = Users._auth_reset_password_check_token(self, cr, uid, values['token'])
|
data = Users._auth_reset_password_check_token(cr, uid, values.get('token', ''))
|
||||||
if data:
|
if data:
|
||||||
Users.write(cr, 1, data['uid'], {'password': pw}, context=context)
|
Users.write(cr, 1, data['uid'], {'password': pw}, context=context)
|
||||||
else:
|
else:
|
||||||
|
@ -113,3 +125,8 @@ class auth_reset_password(osv.TransientModel):
|
||||||
return {'value': {'state': 'missmatch'}}
|
return {'value': {'state': 'missmatch'}}
|
||||||
return {'value': {'state': 'draft'}}
|
return {'value': {'state': 'draft'}}
|
||||||
|
|
||||||
|
def onchange_token(self, cr, uid, ids, token, context=None):
|
||||||
|
Users = self.pool.get('res.users')
|
||||||
|
if not Users._auth_reset_password_check_token(cr, uid, token, context=context):
|
||||||
|
return {'value': {'state': 'error'}}
|
||||||
|
return {}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<field name="name">Reset Password</field>
|
<field name="name">Reset Password</field>
|
||||||
<field name="model_id" ref="base.model_res_users"/>
|
<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_from"><![CDATA[${object.company_id.name} <${object.company_id.email}>]]></field>
|
||||||
<field name="email_to">(set by reset_password module)</field>
|
<field name="email_to" eval="False"><!--(set by reset_password module)--></field>
|
||||||
<field name="subject">Password reset</field>
|
<field name="subject">Password reset</field>
|
||||||
<field name="body_text"><![CDATA[
|
<field name="body_text"><![CDATA[
|
||||||
A password reset was requested the OpenERP account linked to this email on ${object._auth_reset_password_host()}
|
A password reset was requested the OpenERP account linked to this email on ${object._auth_reset_password_host()}
|
||||||
|
|
|
@ -3,8 +3,8 @@ openerp.auth_reset_password = function(instance) {
|
||||||
instance.web.Login.include({
|
instance.web.Login.include({
|
||||||
start: function() {
|
start: function() {
|
||||||
var $e = this.$element;
|
var $e = this.$element;
|
||||||
$e.find('.oe_login_switch a').click(function() {
|
$e.find('a.oe_login_switch').click(function() {
|
||||||
$e.find('.oe_login_switch').toggle();
|
$e.find('ul.oe_login_switch').toggle();
|
||||||
var $m = $e.find('form input[name=is_reset_pw]');
|
var $m = $e.find('form input[name=is_reset_pw]');
|
||||||
$m.attr('checked', !$m.is(':checked'));
|
$m.attr('checked', !$m.is(':checked'));
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,7 @@ openerp.auth_reset_password = function(instance) {
|
||||||
}
|
}
|
||||||
var $m = $e.find('form input[name=is_reset_pw]');
|
var $m = $e.find('form input[name=is_reset_pw]');
|
||||||
if ($m.is(':checked')) {
|
if ($m.is(':checked')) {
|
||||||
var email = $e.find('form input[name=email]').val()
|
var email = $e.find('form input[name=email]').val();
|
||||||
return this.do_reset_password(db, email);
|
return this.do_reset_password(db, email);
|
||||||
} else {
|
} else {
|
||||||
return this._super(ev);
|
return this._super(ev);
|
||||||
|
@ -44,7 +44,7 @@ openerp.auth_reset_password = function(instance) {
|
||||||
// cannot log as anonymous or reset_password not installed
|
// cannot log as anonymous or reset_password not installed
|
||||||
self.do_warn(_t('Reset Password'), _.str.sprintf(_t('Reset Password functionnality is not available for database %s'), db), true);
|
self.do_warn(_t('Reset Password'), _.str.sprintf(_t('Reset Password functionnality is not available for database %s'), db), true);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.reset_password = {};
|
instance.reset_password = {};
|
||||||
|
@ -58,11 +58,10 @@ openerp.auth_reset_password = function(instance) {
|
||||||
name: 'Reset Password',
|
name: 'Reset Password',
|
||||||
type: 'ir.actions.act_window',
|
type: 'ir.actions.act_window',
|
||||||
context: {default_token: this.token},
|
context: {default_token: this.token},
|
||||||
res_model: 'reset_password.wizard',
|
res_model: 'auth.reset_password',
|
||||||
target: 'new',
|
target: 'new',
|
||||||
views: [[false, 'form']],
|
views: [[false, 'form']]
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
<t t-extend="Login">
|
<t t-extend="Login">
|
||||||
<t t-jquery="form ul:first">
|
<t t-jquery="form ul:first">
|
||||||
// addClass does not work :(
|
// addClass does not work :(
|
||||||
this.attr('class', 'oe_login_switch');
|
this.attr('class', (this.attr('class') || '') + ' oe_login_switch');
|
||||||
</t>
|
</t>
|
||||||
<t t-jquery="form ul:first li:last" t-operation="after">
|
<t t-jquery="form ul:first li:last" t-operation="after">
|
||||||
<li>
|
<li>
|
||||||
<a href="#">Forgot your password?</a>
|
<a class="oe_login_switch" href="#">Forgot your password?</a>
|
||||||
</li>
|
</li>
|
||||||
</t>
|
</t>
|
||||||
<t t-jquery="form ul:first" t-operation="after">
|
<t t-jquery="form ul:first" t-operation="after">
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<li>Email</li>
|
<li>Email</li>
|
||||||
<li><input type="email" name="email"/></li>
|
<li><input type="email" name="email"/></li>
|
||||||
<li><button name="submit">Reset Password</button></li>
|
<li><button name="submit">Reset Password</button></li>
|
||||||
<li><a href="#">< Back</a></li>
|
<li><a class="oe_login_switch" href="#">< Back</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|
Loading…
Reference in New Issue