Commit 8b6da72e authored by Penom Nom's avatar Penom Nom
Browse files

gestion of ng6 administrator

parent daedfdb6
......@@ -29,15 +29,7 @@ from ng6.t3MySQLdb import t3MySQLdb
from ng6.project import Project
from ng6.run import Run
def adminlogin(login):
t3mysql = t3MySQLdb()
try:
t3mysql.get_user_id(login)
return login
except:
raise argparse.ArgumentTypeError("Login '" + login + "' does not exists! Please provide a valid login!")
from workflows.types import adminlogin
class BasicNG6Workflow (Workflow):
......
......@@ -72,6 +72,28 @@ class t3MySQLdb(object):
conn.close()
return id
def is_ng6admin(self, login):
"""
Return true if the login is a ng6 administrator
@return: id
@param login: the login name
"""
conn = connect(self.host, self.user, self.passwd, self.db)
curs = conn.cursor()
req = "SELECT uid, usergroup FROM fe_users WHERE username = '" + str(login) + "'"
curs.execute(req)
try:
data = curs.fetchall()
id = data[0][0]
grp = data[0][1].split(',')
is_admin = True if "1" in grp else False
except:
raise Exception('t3MySQLdb', 'The login ' + login + ' does not exist.')
curs.close()
conn.close()
return is_admin
def get_users (self, project_id, right):
"""
Select the users ids for a project and a level of rigth
......
......@@ -562,6 +562,16 @@ class tx_nG6_eid {
}
}
else if ( $type == 'add_to_ng6_admin'){
$userid = trim(t3lib_div::_GP('userid'));
tx_nG6_db::add_to_ng6_admin($userid);
}
else if ( $type == 'delete_from_ng6_admin'){
$userids = trim(t3lib_div::_GP('userids'));
$userids = explode(',', $userids);
tx_nG6_db::remove_from_ng6_admin($userids);
}
else if($type == 'update_user'){
$email = trim(t3lib_div::_GP('email'));
$first_name = trim(t3lib_div::_GP('first_name'));
......@@ -665,6 +675,7 @@ class tx_nG6_eid {
$smarty->assign('projects', $projects);
$smarty->assign('is_at_least_admin_of_1_project', $is_at_least_admin_of_1_project);
$smarty->assign('login_user', $login_user);
$smarty->assign('is_ng6_admin', tx_nG6_db::is_ng6_administrator($user_id) ? true : false);
print $smarty->fetch('project_table.tpl');
} elseif($type == 'analyses_table') {
......@@ -712,7 +723,11 @@ class tx_nG6_eid {
tx_nG6_utils::hash_password(trim(t3lib_div::_GP('password'))),
trim(t3lib_div::_GP('pid')),
"Demo project",
"This project presents demonstration workflows"
"This project presents demonstration workflows",
trim(t3lib_div::_GP('title')),
trim(t3lib_div::_GP('organism')),
trim(t3lib_div::_GP('location'))
);
// if there is a result, then log the user
if ($res2) {
......
......@@ -1648,6 +1648,89 @@ class tx_nG6_db {
return $authorized;
}
/**
* Return true if the user is a ng6 administrator (belongs to ng6_admin group)
*
* @param string $user_id The user id
* @param unknown $user_id
*/
function is_ng6_administrator($user_id){
$is_ng6_admin = false;
if( $user_id != null){
$user_group = tx_nG6_db::get_user_usergroup($user_id);
$groups = explode ( ',', $user_group) ;
if (in_array('1', $groups)){
$is_ng6_admin = true;
}
}
return $is_ng6_admin;
}
/**
* Return the list of ng6_admin users
*/
function get_ng6_admin_users(){
$ng6_admin_users = null;
$queryParts = Array(
'SELECT' => 'fe_users.uid, fe_users.username, fe_users.first_name, fe_users.last_name, fe_users.email',
'FROM' => 'fe_users',
'WHERE' => '',
'GROUPBY' => '',
'ORDERBY' => '',
'LIMIT' => '',
);
$res = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
while($res_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
if (tx_nG6_db::is_ng6_administrator($res_row['uid'])){
$ng6_admin_users[ ] = array(
'id' => $res_row['uid'],
'username' => $res_row['username'],
'first_name' => $res_row['first_name'],
'last_name' => $res_row['last_name'],
'email' => $res_row['email']
);
}
}
return $ng6_admin_users;
}
/**
* Add an existing user to the ng6_admin group
* @param unknown $userid
*/
function add_to_ng6_admin( $userid ){
$user_info = tx_nG6_db::get_user_informations($userid);
$pieces = explode(",", $user_info['usergroup']);
if (!in_array("1", $pieces)) {
$pieces [] = "1";
$group = implode(",", $pieces);
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('fe_users', 'fe_users.uid='.$userid, array('fe_users.usergroup' => $group));
}
}
/**
* Remove an user from the ng6_admin group
* @param unknown $userids
*/
function remove_from_ng6_admin( $userids ){
foreach ($userids as $userid){
$user_info = tx_nG6_db::get_user_informations($userid);
$pieces = explode(",", $user_info['usergroup']);
if (in_array('1', $pieces)){
unset($pieces[array_search('1',$pieces)]);
$group = implode(",", $pieces);
$GLOBALS['TYPO3_DB']->exec_UPDATEquery ('fe_users', 'fe_users.uid='.$userid, array('fe_users.usergroup' => $group));
}
}
}
/**
* Return if the user is a superuser (administrator) for the specified project/run/analyse
*
......@@ -1939,12 +2022,14 @@ class tx_nG6_db {
$distinct = array();
while($res_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
if( $col == 'title') {
if ($res_row["title"] != 'ng6_admin'){
$res_tab[] = array(
'uid' => $res_row['uid'],
'title' => $res_row['title'],
'organism' => $res_row['tx_nG6_organism'],
'location' => $res_row['tx_nG6_location']
);
}
} else {
if( !isset($distinct[$res_row[$col]]) ) {
$res_tab[] = array(
......@@ -1966,7 +2051,7 @@ class tx_nG6_db {
*/
function get_user_informations($user_id){
$queryParts = Array(
'SELECT' => 'fe_users.uid, fe_users.username, fe_users.last_name, fe_users.first_name, fe_users.password, fe_users.email, fe_users.cruser_id',
'SELECT' => 'fe_users.uid, fe_users.username, fe_users.last_name, fe_users.first_name, fe_users.password, fe_users.email, fe_users.cruser_id, fe_users.usergroup',
'FROM' => 'fe_users',
'WHERE' => 'fe_users.uid='.$user_id,
'GROUPBY' => '',
......@@ -1983,7 +2068,8 @@ class tx_nG6_db {
'last_name' => $res_row['last_name'],
'password' => $res_row['password'],
'email' => $res_row['email'],
'cruser_id' => $res_row['cruser_id']
'cruser_id' => $res_row['cruser_id'],
'usergroup' => $res_row['usergroup']
);
}
return $res_tab;
......@@ -2188,7 +2274,13 @@ class tx_nG6_db {
* @param string user_name the user id
* @return bool true if ok false else
*/
function finalize_installation($user_id, $user_name, $first_name, $last_name, $email, $password, $pid, $project, $descr){
function finalize_installation($user_id, $user_name, $first_name, $last_name, $email, $password, $pid, $project, $descr,
$group_name, $organism, $location){
$group_id = tx_nG6_db::get_group_id($group_name);
if( !isset($group_id) ){
$group_id = tx_nG6_db::create_new_group($user_id, $group_name, $organism, $location);
}
$fe_user_datas = array(
'username' => $user_name,
......@@ -2197,7 +2289,8 @@ class tx_nG6_db {
'last_name' => $last_name,
'email' => $email,
'password' => $password,
'tstamp' => time()
'tstamp' => time(),
'usergroup' => $group_id
);
$be_user_datas = array(
'username' => $user_name,
......@@ -2214,6 +2307,7 @@ class tx_nG6_db {
$res = $GLOBALS['TYPO3_DB']->exec_UPDATEquery('fe_users', 'uid='.$user_id, $fe_user_datas );
if ($res == True){
tx_nG6_db::add_to_ng6_admin($user_id);
$res2 = $GLOBALS['TYPO3_DB']->exec_UPDATEquery('be_users', 'uid='.$user_id, $be_user_datas );
}
if ($res == True){
......@@ -2298,6 +2392,7 @@ class tx_nG6_db {
);
$GLOBALS['TYPO3_DB']->exec_INSERTquery('fe_groups', $group_datas);
return $GLOBALS['TYPO3_DB']->sql_insert_id();
}
/**
......
......@@ -81,6 +81,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</div>
</div>
<div class="control-group">
<label class="control-label">Laboratory</label>
<div class="controls">
<input type="text" id="title_val" class="group_typeahead" name="title_val" placeholder="Laboratory"/>
</div>
</div>
<div class="control-group">
<label class="control-label">Organism</label>
<div class="controls">
<input type="text" id="organism_val" class="group_typeahead" name="organism_val" placeholder="Organism"/>
</div>
</div>
<div class="control-group">
<label class="control-label">Location</label>
<div class="controls">
<input type="text" id="location_val" class="group_typeahead" name="location_val" placeholder="Location"/>
</div>
</div>
</form>
<div style="float:right;margin-top:10px">
<button class="btn" id="raz_form_install"><i class="icon-repeat"></i> Clear form</button>
......
......@@ -73,7 +73,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
{/if}
{/foreach}
</tbody>
{if $is_at_least_admin_of_1_project && $login_user}
{if $is_ng6_admin}
<tfoot>
<tr>
<th align="left" colspan="4">
......
......@@ -38,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#statistics" data-toggle="tab">Statistics</a></li>
<li><a href="#wf_monitoring" data-toggle="tab">Workflows monitoring</a></li>
<li><a href="#admin_management" data-toggle="tab">Admin management</a></li>
</ul>
<div id="myTabContent" class="tab-content">
......@@ -158,7 +159,71 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<div class="tab-pane fade" id="wf_monitoring"></div>
<div class="tab-pane fade" id="admin_management">
<div id="admin_users">
<p>This table allows you to add a user to the list of ng6 administrator</p>
<table class="table table-striped table-bordered dataTable" id="users_data_table">
<thead>
<tr>
<th><center><input type="checkbox" id="chk_all_user"></center></th>
<th nowrap>Login</th>
<th>Last name</th>
<th>First name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{foreach from=$ng6_admin_users key=c_user_id item=user_values}
{* highlight user personnal line *}
{assign var="emphasis" value=""}
{if $user_values.id==$user_id}
{assign var="emphasis" value="tx-nG6-pi1-line-emphasis"}
{/if}
<tr id="tr_user_{$user_values.id}" class="{$emphasis}">
{if $user_values.id == $user_id }
<td></td>
{else}
<td><center><input type="checkbox" id="chk_user_{$user_values.id}" value="user_{$user_values.id}" /></center></td>
{/if}
<td>{$user_values.username}</td>
<td>{$user_values.last_name}</td>
<td>{$user_values.first_name}</td>
<td>{$user_values.email}</td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<th align="left" colspan="8">
With selection :
<div class="btn-group">
<button id="add_admin" type="button" class="btn btn-small" ><i class="icon-plus"></i> add administrator</button>
<button id="del_admin" type="button" class="btn multipleu-selection-btn btn-small"><i class="icon-minus"></i> delete administrator</button>
</div>
</th>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
{* Modal initialization *}
{* Global tmpl *}
<div id="ng6modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="modal-label-tmpl" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">x</button>
<h3 id="modal-label-tmpl">Modal header</h3>
</div>
<div id="modal-body-tmpl" class="modal-body"></div>
<div id="modal-foot-tmpl" class="modal-footer"></div>
</div>
<!-- statusModal -->
......
......@@ -61,6 +61,7 @@ class tx_nG6_pi6 extends tslib_pibase {
$GLOBALS['TSFE']->additionalHeaderData[$this->prefixId] = '
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/bootstrap.min.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/bootstrap-typeahead.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/tx_nG6_pi6.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/highstock.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jquery.highcharts.exporting.js"></script>
......@@ -72,6 +73,7 @@ class tx_nG6_pi6 extends tslib_pibase {
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-availablewf.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-wfform.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/jflow-wfstatus.js"></script>
<script type="text/javascript" src="'.t3lib_extMgm::siteRelPath($this->extKey).'res/js/tx_nG6_utils.js"></script>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/DT_bootstrap.css"/>
<link type="text/css" rel="stylesheet" media="screen" href="'.t3lib_extMgm::siteRelPath($this->extKey).'res/css/tx_nG6.css"/>';
......@@ -92,6 +94,7 @@ class tx_nG6_pi6 extends tslib_pibase {
$smarty->assign('server_url', $this->conf['server_url']);
$distribution = tx_nG6_db::select_projects_repartition('create_user', 'title');
$smarty->assign('distribution', $distribution);
$smarty->assign('ng6_admin_users', tx_nG6_db::get_ng6_admin_users() );
return $smarty->fetch('administration_view.tpl');
}
}
......
......@@ -916,8 +916,9 @@ $(function () {
username_val: { required: true },
user_password_pwd_val: { required: true },
user_password_pwd2_val: { required: true, equalTo: "#user_password_pwd_val"},
project_name_val: { required: true },
description_val: { required: true }
title_val : { required : true },
organism_val : { required : true },
location_val : { required : true}
},
messages: {
first_name_val: null,
......@@ -926,8 +927,9 @@ $(function () {
username_val: null,
user_password_pwd_val: null,
user_password_pwd2_val: "Same password is required",
project_name_val: null,
description_val: null
title_val: null,
organism_val: null,
location_val: null
},
submitHandler: function(form) {
var val_url = "index.php?eID=tx_nG6&type=install";
......@@ -937,6 +939,9 @@ $(function () {
val_url += "&password=" + $("#user_password_pwd_val").val();
val_url += "&email=" + $("#email_val").val();
val_url += "&pid=" + $("#pid").val();
val_url += "&title=" + $("#title_val").val();
val_url += "&organism=" + $("#organism_val").val();
val_url += "&location=" + $("#location_val").val();
$.ajax({
url: val_url,
success: function(val, status, xhr) {
......
......@@ -66,6 +66,14 @@ $(function () {
})
})
updateUsersButtonStatus();
$("[id^=chk_user_]").change(function() {
updateUsersButtonStatus();
});
$("#chk_all_user").change(function() {
updateUsersButtonStatus();
});
$(":checkbox").change(function(){
updateButtons();
})
......@@ -96,8 +104,175 @@ $(function () {
$('#statusModal').modal();
});
$('#add_admin').click(function(){
$("#modal-label-tmpl").html("Add a new ng6 admin user");
var add_ng6_admin = '<div id="error_message" class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button></div>';
add_ng6_admin += '<div class="tx-nG6-pi1-add-new">Seek the user using the autocompletion fields<br /> <br /> ';
add_ng6_admin += '<form class="form-horizontal" id="new_ng6_admin_user">';
add_ng6_admin += ' <input type="hidden" id="userid_val" name="userid_val" />';
add_ng6_admin += ' <div class="control-group">';
add_ng6_admin += ' <label class="control-label">Login</label>';
add_ng6_admin += ' <div class="controls">';
add_ng6_admin += ' <input type="text" id="username_val" class="typeahead" name="username_val" placeholder="Login"/>';
add_ng6_admin += ' </div>';
add_ng6_admin += ' </div>';
add_ng6_admin += ' <div class="control-group">';
add_ng6_admin += ' <label class="control-label">Last name</label>';
add_ng6_admin += ' <div class="controls">';
add_ng6_admin += ' <input type="text" id="last_name_val" class="typeahead" name="last_name_val" placeholder="Last name"/> ';
add_ng6_admin += ' </div>';
add_ng6_admin += ' </div>';
add_ng6_admin += ' <div class="control-group">';
add_ng6_admin += ' <label class="control-label">First name</label>';
add_ng6_admin += ' <div class="controls">';
add_ng6_admin += ' <input type="text" id="first_name_val" class="typeahead" name="first_name_val" placeholder="First name"/>';
add_ng6_admin += ' </div>';
add_ng6_admin += ' </div>';
add_ng6_admin += ' <input type="hidden" id="added_userid_val" name="added_userid_val" />';
add_ng6_admin += '</form>';
add_ng6_admin += '</div>';
$("#modal-body-tmpl").html(add_ng6_admin);
$("#modal-foot-tmpl").html('<button class="btn" id="raz_form"><i class="icon-repeat"></i> Clear form</a>' +
'<button class="btn" data-dismiss="modal" aria-hidden="true"><i class="icon-remove"></i> Close</button>' +
'<button id="modal-btn-addng6admin" class="btn btn-primary"><i class="icon-user icon-white"></i> Add</button>');
$("#ng6modal").modal().ready(function() {
$("#error_message").hide();
$('.typeahead').typeahead({
minLength: 2,
onselect: function(item) {
$("#new_member div.control-group").removeClass("error");
$(".btn-danger").removeClass("btn-danger");
$(".icon-wrench").removeClass("icon-white");
$("#last_name_val").val(item.last_name);
$("#first_name_val").val(item.first_name);
$("#username_val").val(item.username);
$("#userid_val").val(item.uid);
lock_fields(1);
},
source: function (typeahead, query) {
var gender = $(typeahead["$element"][0]).attr("id").split("_val")[0];
$.ajax({
url: "index.php?eID=tx_nG6&type=autocomplete&gender="+gender+ "&name_start=" + query,
dataType: 'json',
success: function (users) {
var data = new Array();
for (index in users) {
users[index]['value'] = users[index][gender];
data.push(users[index]);
}
typeahead.process(data);
}
});
}
});
// empty the form
$("#raz_form").click(function(){
$("#last_name_val").val("");
$("#first_name_val").val("");
$("#username_val").val("");
$("#userid_val").val("");
lock_fields(0); // unlock fields
$(".btn-danger").removeClass("btn-danger");
$(".icon-wrench").removeClass("icon-white");
$("#error_message").hide();
});
// lock/unlock fields when autocomplete
function lock_fields(order){
// lock fields
if(order == 1){
$("#username_val").attr('disabled', 'disabled');
$("#last_name_val").attr('disabled', 'disabled');
$("#first_name_val").attr('disabled', 'disabled');
} else if(order == 0){
$("#username_val").removeAttr('disabled');
$("#last_name_val").removeAttr('disabled');
$("#first_name_val").removeAttr('disabled');
}
}
if($("#username_val").attr('disabled') != 'disabled'){
$("#new_ng6_admin_user").validate({
rules: {
first_name_val: { required: true },
last_name_val: { required: true },
username_val: { required: true },
},
messages: {
first_name_val: null,
last_name_val: null,
username_val: null,
},
submitHandler: function(form) {
var val_url = "index.php?eID=tx_nG6&type=add_to_ng6_admin";
val_url += "&userid=" + $("#userid_val").val();
$.ajax({
url: val_url,
success: function(val) {
$("#ng6modal").modal('hide');
set_active_tab('admin_management');
}
});
}
});
}
});
$("#modal-btn-addng6admin").click( function() {
$("#new_ng6_admin_user").submit();
});
});
$('#del_admin').click(function(){
$("#modal-label-tmpl").html("Delete");
$("#modal-body-tmpl").html("Are you sure you want to delete this user from admin group?");
$("#modal-foot-tmpl").html('<button class="btn" data-dismiss="modal" aria-hidden="true">No</button>' +
'<button id="modal-btn-yes" class="btn btn-primary">Yes</button>');
$("#ng6modal").modal();
$("#modal-btn-yes").click( function() {
var val_url = "index.php?eID=tx_nG6&type=delete_from_ng6_admin";
val_url += "&userids=" ;
var arr = [];
$(':checked[id^=chk_user]').each(function(i){
arr.push( $(this).val().split("_" , 2)[1] );
});
val_url += arr.join(',');
$.ajax({
url: val_url,
success: function(val) {
$("#ng6modal").modal('hide');
set_active_tab('admin_management');
}
});
});
});