Browse Source

[11.0][ADD] easy_switch_user (#6)

* [ADD] easy_switch_user
pull/13/head
Dennis Sluijk 7 years ago
committed by Stefan Rijnhart (Opener)
parent
commit
a5324c4bed
  1. 55
      easy_switch_user/README.rst
  2. 4
      easy_switch_user/__init__.py
  3. 23
      easy_switch_user/__manifest__.py
  4. 4
      easy_switch_user/controllers/__init__.py
  5. 14
      easy_switch_user/controllers/main.py
  6. 153
      easy_switch_user/static/src/js/switch_user.js
  7. 36
      easy_switch_user/static/src/xml/switch_user.xml
  8. 11
      easy_switch_user/templates/assets.xml
  9. 4
      easy_switch_user/tests/__init__.py
  10. 30
      easy_switch_user/tests/test_controller.py

55
easy_switch_user/README.rst

@ -0,0 +1,55 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: https://www.gnu.org/licenses/agpl
:alt: License: AGPL-3
================
Easy Switch User
================
This module lets administrators and developers quickly change user to test e.g. access rights.
Usage
=====
To use this module, you need to:
#. Click on the caret in the system tray
#. Select the user you want to switch to
#. Login (only required once)
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/250/11.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/server-ux/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Contributors
------------
* Dennis Sluijk <d.sluijk@onestein.nl>
Do not contact contributors directly about support or help with technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

4
easy_switch_user/__init__.py

@ -0,0 +1,4 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import controllers

23
easy_switch_user/__manifest__.py

@ -0,0 +1,23 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
'name': 'Easy Switch User',
'summary': 'Lets administrators and developers quickly '
'change user to test e.g. access rights',
'category': 'Tools',
'version': '11.0.1.0.0',
'author': 'Onestein, Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/server-ux',
'license': 'AGPL-3',
'depends': [
'web'
],
'qweb': [
'static/src/xml/switch_user.xml'
],
'data': [
'templates/assets.xml'
],
'installable': True,
}

4
easy_switch_user/controllers/__init__.py

@ -0,0 +1,4 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import main

14
easy_switch_user/controllers/main.py

@ -0,0 +1,14 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import http
from odoo.http import route
class SwitchController(http.Controller):
@route('/easy_switch_user/switch', type='json', auth="none")
def switch(self, login, password):
request = http.request
uid = request.session.authenticate(request.db, login, password)
if uid is False:
raise Exception('Login Failed')

153
easy_switch_user/static/src/js/switch_user.js

@ -0,0 +1,153 @@
/* Copyright 2018 Onestein
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
odoo.define('easy_switch_user', function(require) {
var Widget = require('web.Widget');
var SystrayMenu = require('web.SystrayMenu');
var UserMenu = require('web.UserMenu');
var session = require('web.session');
var Dialog = require('web.Dialog');
var core = require('web.core');
var ajax = require('web.ajax');
var qweb = core.qweb;
var _t = core._t;
var SwitchUserMenu = Widget.extend({
template: 'SwitchUserMenu',
events: {
'click .dropdown-menu li a[data-user-login]': 'user_selected'
},
start: function() {
var res = this._super.apply(this, arguments);
this.loadUsers().then(this.populate.bind(this));
return res;
},
loadUsers: function() {
return this._rpc({
model: 'res.users',
method: 'search_read',
order: 'name asc'
});
},
populate: function(users) {
var stored = this.get_stored_passwords();
var users_stored = [];
var users_not_stored = [];
for(var i in users) {
if(users[i].login in stored) {
users_stored.push(users[i]);
} else {
users_not_stored.push(users[i]);
}
}
this.$('.dropdown-menu').html('');
this.populate_users(users_stored);
if(users_stored.length > 0) {
this.$('.dropdown-menu').append('<li class="divider"></li>');
}
this.populate_users(users_not_stored);
},
populate_users: function(users) {
var self = this;
_.each(users, function(user) {
var inside = session.uid === user.id
? '<b>' + user.name + ' (' + user.login + ')</b>'
: user.name + ' (' + user.login + ')';
self.$('.dropdown-menu').append(
'<li><a href="#" data-user-login="' + user.login + '">' + inside + '</a></li>'
);
});
},
get_stored_passwords: function() {
var val = sessionStorage.getItem('easy_switch_user');
if (!val) {
return {};
}
return JSON.parse(val);
},
store_password: function(login, password) {
var store = {};
var val = sessionStorage.getItem('easy_switch_user');
if (val) {
store = JSON.parse(val);
}
store[login] = password;
sessionStorage.setItem('easy_switch_user', JSON.stringify(store));
},
user_selected: function(e) {
var self = this;
var user_login = $(e.currentTarget).attr('data-user-login');
var passwords = this.get_stored_passwords();
if (user_login in passwords) {
this.switch_user(user_login, passwords[user_login]);
} else {
var dialog = new SwitchUserLoginDialog(this, user_login);
dialog.on('login', this, function(result) {
dialog.hideError();
self.switch_user(user_login, result.password, result.store).fail(function() {
dialog.showError();
});
});
dialog.open();
}
},
switch_user: function(login, password, store) {
if (typeof(store) === 'undefined') {
store = false;
}
var self = this;
return ajax.jsonRpc('/easy_switch_user/switch', 'call', {
login: login,
password: password
}).then(function() {
if(store) {
self.store_password(login, password);
}
window.location.reload();
});
}
});
SystrayMenu.Items.push(SwitchUserMenu);
UserMenu.include({
do_action: function(action, options) {
var def = this._super(action, options);
if (action == 'logout') {
sessionStorage.removeItem('easy_switch_user');
}
return def;
}
});
var SwitchUserLoginDialog = Dialog.extend({
init: function(parent, user_login) {
this._super(parent, {
title: _t('Switch User'),
$content: $(qweb.render('SwitchUserLoginDialog', {'login': user_login})),
buttons: [
{ text: _t("Login"), classes: 'btn-primary', click: this.login },
{ text: _t("Cancel"), close: true }
]
});
},
login: function() {
this.trigger('login', {
'password': this.$('input[type="password"]').val(),
'store': this.$('input[type="checkbox"]').is(':checked')
});
},
showError: function() {
this.$('.alert-danger').removeClass('hidden');
},
hideError: function() {
this.$('.alert-danger').addClass('hidden');
}
});
return {
Menu: SwitchUserMenu,
Dialog: SwitchUserLoginDialog
};
});

36
easy_switch_user/static/src/xml/switch_user.xml

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Onestein
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<template>
<t t-name="SwitchUserMenu">
<li class="o_switch_user_menu">
<a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#">
<span class="oe_topbar_name"/> <span class="caret"/>
</a>
<ul class="dropdown-menu" role="menu"/>
</li>
</t>
<t t-name="SwitchUserLoginDialog">
<div>
<div class="form-group">
<label>Login</label>
<input type="text" disabled="disabled" class="form-control" t-att-value="login" />
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control"/>
</div>
<div class="checkbox">
<label>
<input type="checkbox"/> Store password (remembers it until you close this tab)
</label>
</div>
<div class="alert alert-danger hidden">
Login failed.
</div>
</div>
</t>
</template>

11
easy_switch_user/templates/assets.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2018 Onestein
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<template id="assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/easy_switch_user/static/src/js/switch_user.js"></script>
</xpath>
</template>
</odoo>

4
easy_switch_user/tests/__init__.py

@ -0,0 +1,4 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_controller

30
easy_switch_user/tests/test_controller.py

@ -0,0 +1,30 @@
# Copyright 2018 Onestein
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import http
from odoo.tests.common import TransactionCase
from odoo.addons.easy_switch_user.controllers.main import SwitchController
class FakeRequest(object):
def __init__(self, env):
self.db = env.cr.dbname
self.session = FakeSession()
class FakeSession(object):
def authenticate(self, db, login, password):
return False
class TestController(TransactionCase):
def setUp(self):
super(TestController, self).setUp()
self.ctrl = SwitchController()
def test_switch(self):
old_request = http.request
http.request = FakeRequest(self.env)
with self.assertRaises(Exception):
self.ctrl.switch('unknown_user', '1234567890')
http.request = old_request
Loading…
Cancel
Save