mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-28 14:50:08 +03:00
Feature #3541: New methods to manage group admins in the core
This commit is contained in:
parent
614758b294
commit
d294d96a52
@ -75,6 +75,26 @@ public:
|
||||
return del_collection_id(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a User to the admin set. ACL Rules are updated only for this user.
|
||||
*
|
||||
* @param user_id ID of the user
|
||||
* @param error_msg Returns the error reason, if any
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int add_admin(int user_id, string& error_msg);
|
||||
|
||||
/**
|
||||
* Deletes a User from the admin set. ACL Rules are updated only for this user.
|
||||
*
|
||||
* @param user_id ID of the user
|
||||
* @param error_msg Returns the error reason, if any
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int del_admin(int user_id, string& error_msg);
|
||||
|
||||
/**
|
||||
* Object quotas, provides set and check interface
|
||||
*/
|
||||
@ -113,7 +133,8 @@ private:
|
||||
Group(int id, const string& name):
|
||||
PoolObjectSQL(id,GROUP,name,-1,-1,"","",table),
|
||||
ObjectCollection("USERS"),
|
||||
quota()
|
||||
quota(),
|
||||
admins("ADMINS")
|
||||
{
|
||||
// Allow users in this group to see it
|
||||
group_u = 1;
|
||||
@ -126,6 +147,18 @@ private:
|
||||
delete obj_template;
|
||||
};
|
||||
|
||||
// *************************************************************************
|
||||
// Administrators
|
||||
// *************************************************************************
|
||||
|
||||
/**
|
||||
* Stores a collection with the admin users
|
||||
*/
|
||||
ObjectCollection admins;
|
||||
|
||||
void add_admin_rules(int user_id);
|
||||
void del_admin_rules(int user_id);
|
||||
|
||||
// *************************************************************************
|
||||
// DataBase implementation (Private)
|
||||
// *************************************************************************
|
||||
|
@ -85,6 +85,16 @@ public:
|
||||
return set<int> (collection_set);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the collection contains the given id
|
||||
* @param id ID to search
|
||||
* @return true if the collection contains the given id
|
||||
*/
|
||||
bool collection_contains(int id)
|
||||
{
|
||||
return collection_set.count(id) > 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
@ -66,6 +66,66 @@ public:
|
||||
RequestAttributes& att);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class GroupEditAdmin : public Request
|
||||
{
|
||||
public:
|
||||
void request_execute(xmlrpc_c::paramList const& _paramList,
|
||||
RequestAttributes& att);
|
||||
|
||||
protected:
|
||||
GroupEditAdmin( const string& method_name,
|
||||
const string& help,
|
||||
const string& params)
|
||||
:Request(method_name,params,help)
|
||||
{
|
||||
Nebula& nd = Nebula::instance();
|
||||
pool = nd.get_gpool();
|
||||
upool = nd.get_upool();
|
||||
|
||||
auth_object = PoolObjectSQL::GROUP;
|
||||
auth_op = AuthRequest::ADMIN;
|
||||
};
|
||||
|
||||
UserPool* upool;
|
||||
|
||||
virtual int edit_admin(Group* group, int user_id, string& error_msg) = 0;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class GroupAddAdmin : public GroupEditAdmin
|
||||
{
|
||||
public:
|
||||
GroupAddAdmin():
|
||||
GroupEditAdmin( "GroupAddAdmin",
|
||||
"Adds a user to the group admin set",
|
||||
"A:sii"){};
|
||||
|
||||
~GroupAddAdmin(){};
|
||||
|
||||
int edit_admin(Group* group, int user_id, string& error_msg);
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class GroupDelAdmin : public GroupEditAdmin
|
||||
{
|
||||
public:
|
||||
GroupDelAdmin():
|
||||
GroupEditAdmin( "GroupDelAdmin",
|
||||
"Removes a user from the group admin set",
|
||||
"A:sii"){};
|
||||
|
||||
~GroupDelAdmin(){};
|
||||
|
||||
int edit_admin(Group* group, int user_id, string& error_msg);
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -214,6 +214,7 @@ string& Group::to_xml_extended(string& xml, bool extended) const
|
||||
{
|
||||
ostringstream oss;
|
||||
string collection_xml;
|
||||
string admins_xml;
|
||||
string template_xml;
|
||||
|
||||
ObjectCollection::to_xml(collection_xml);
|
||||
@ -223,7 +224,8 @@ string& Group::to_xml_extended(string& xml, bool extended) const
|
||||
"<ID>" << oid << "</ID>" <<
|
||||
"<NAME>" << name << "</NAME>" <<
|
||||
obj_template->to_xml(template_xml) <<
|
||||
collection_xml;
|
||||
collection_xml <<
|
||||
admins.to_xml(admins_xml);
|
||||
|
||||
if (extended)
|
||||
{
|
||||
@ -276,6 +278,19 @@ int Group::from_xml(const string& xml)
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
|
||||
// Set of Admin IDs
|
||||
ObjectXML::get_nodes("/GROUP/ADMINS", content);
|
||||
|
||||
if (content.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc += admins.from_xml_node(content[0]);
|
||||
|
||||
ObjectXML::free_nodes(content);
|
||||
content.clear();
|
||||
|
||||
// Get associated metadata for the group
|
||||
ObjectXML::get_nodes("/GROUP/TEMPLATE", content);
|
||||
|
||||
@ -296,3 +311,181 @@ int Group::from_xml(const string& xml)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Group::add_admin(int user_id, string& error_msg)
|
||||
{
|
||||
int rc;
|
||||
ostringstream oss;
|
||||
|
||||
if ( collection_contains(user_id) == false )
|
||||
{
|
||||
oss << "User " << user_id << " is not part of Group "
|
||||
<< oid << ".";
|
||||
|
||||
error_msg = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = admins.add_collection_id(user_id);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
oss << "User " << user_id << " is already an administrator of Group "
|
||||
<< oid << ".";
|
||||
|
||||
error_msg = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
add_admin_rules(user_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void Group::add_admin_rules(int user_id)
|
||||
{
|
||||
int rc;
|
||||
string error_msg;
|
||||
|
||||
AclManager* aclm = Nebula::instance().get_aclm();
|
||||
|
||||
// #<uid> USER/@<gid> USE+MANAGE+ADMIN+CREATE *
|
||||
rc = aclm->add_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
|
||||
PoolObjectSQL::USER |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
AuthRequest::USE |
|
||||
AuthRequest::MANAGE |
|
||||
AuthRequest::ADMIN |
|
||||
AuthRequest::CREATE,
|
||||
|
||||
AclRule::ALL_ID,
|
||||
|
||||
error_msg);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP/@<gid> USE+MANAGE *
|
||||
rc = aclm->add_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
|
||||
PoolObjectSQL::VM |
|
||||
PoolObjectSQL::NET |
|
||||
PoolObjectSQL::IMAGE |
|
||||
PoolObjectSQL::TEMPLATE |
|
||||
PoolObjectSQL::DOCUMENT |
|
||||
PoolObjectSQL::SECGROUP |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
AuthRequest::USE |
|
||||
AuthRequest::MANAGE,
|
||||
|
||||
AclRule::ALL_ID,
|
||||
|
||||
error_msg);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
int Group::del_admin(int user_id, string& error_msg)
|
||||
{
|
||||
int rc = admins.del_collection_id(user_id);
|
||||
|
||||
if (rc == -1)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "User " << user_id << " is not an administrator of Group "
|
||||
<< oid << ".";
|
||||
|
||||
error_msg = oss.str();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
del_admin_rules(user_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void Group::del_admin_rules(int user_id)
|
||||
{
|
||||
int rc;
|
||||
string error_msg;
|
||||
|
||||
AclManager* aclm = Nebula::instance().get_aclm();
|
||||
|
||||
// #<uid> USER/@<gid> USE+MANAGE+ADMIN+CREATE *
|
||||
rc = aclm->del_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
|
||||
PoolObjectSQL::USER |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
AuthRequest::USE |
|
||||
AuthRequest::MANAGE |
|
||||
AuthRequest::ADMIN |
|
||||
AuthRequest::CREATE,
|
||||
|
||||
AclRule::ALL_ID,
|
||||
|
||||
error_msg);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
|
||||
// #<uid> VM+NET+IMAGE+TEMPLATE+DOCUMENT+SECGROUP/@<gid> USE+MANAGE *
|
||||
rc = aclm->del_rule(
|
||||
AclRule::INDIVIDUAL_ID |
|
||||
user_id,
|
||||
|
||||
PoolObjectSQL::VM |
|
||||
PoolObjectSQL::NET |
|
||||
PoolObjectSQL::IMAGE |
|
||||
PoolObjectSQL::TEMPLATE |
|
||||
PoolObjectSQL::DOCUMENT |
|
||||
PoolObjectSQL::SECGROUP |
|
||||
AclRule::GROUP_ID |
|
||||
oid,
|
||||
|
||||
AuthRequest::USE |
|
||||
AuthRequest::MANAGE,
|
||||
|
||||
AclRule::ALL_ID,
|
||||
|
||||
error_msg);
|
||||
|
||||
if (rc < 0)
|
||||
{
|
||||
NebulaLog::log("GROUP",Log::ERROR,error_msg);
|
||||
}
|
||||
}
|
||||
|
@ -484,23 +484,31 @@ void RequestManager::register_xml_methods()
|
||||
xmlrpc_c::method * group_allocate_pt;
|
||||
xmlrpc_c::method * group_update_pt;
|
||||
xmlrpc_c::method * group_delete_pt;
|
||||
xmlrpc_c::method * group_add_admin_pt;
|
||||
xmlrpc_c::method * group_del_admin_pt;
|
||||
|
||||
if (nebula.is_federation_slave())
|
||||
{
|
||||
group_allocate_pt = new RequestManagerProxy("one.group.allocate");
|
||||
group_delete_pt = new RequestManagerProxy("one.group.delete");
|
||||
group_update_pt = new RequestManagerProxy("one.group.update");
|
||||
group_add_admin_pt = new RequestManagerProxy("one.group.addadmin");
|
||||
group_del_admin_pt = new RequestManagerProxy("one.group.deladmin");
|
||||
}
|
||||
else
|
||||
{
|
||||
group_allocate_pt = new GroupAllocate();
|
||||
group_delete_pt = new GroupDelete();
|
||||
group_update_pt = new GroupUpdateTemplate();
|
||||
group_add_admin_pt = new GroupAddAdmin();
|
||||
group_del_admin_pt = new GroupDelAdmin();
|
||||
}
|
||||
|
||||
xmlrpc_c::methodPtr group_allocate(group_allocate_pt);
|
||||
xmlrpc_c::methodPtr group_delete(group_delete_pt);
|
||||
xmlrpc_c::methodPtr group_update(group_update_pt);
|
||||
xmlrpc_c::methodPtr group_add_admin(group_add_admin_pt);
|
||||
xmlrpc_c::methodPtr group_del_admin(group_del_admin_pt);
|
||||
|
||||
xmlrpc_c::methodPtr group_info(new GroupInfo());
|
||||
xmlrpc_c::methodPtr group_set_quota(new GroupSetQuota());
|
||||
@ -513,6 +521,8 @@ void RequestManager::register_xml_methods()
|
||||
RequestManagerRegistry.addMethod("one.group.info", group_info);
|
||||
RequestManagerRegistry.addMethod("one.group.quota", group_set_quota);
|
||||
RequestManagerRegistry.addMethod("one.group.update", group_update);
|
||||
RequestManagerRegistry.addMethod("one.group.addadmin", group_add_admin);
|
||||
RequestManagerRegistry.addMethod("one.group.deladmin", group_del_admin);
|
||||
|
||||
RequestManagerRegistry.addMethod("one.grouppool.info", grouppool_info);
|
||||
|
||||
|
@ -81,3 +81,113 @@ void GroupSetQuota::
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
void GroupEditAdmin::request_execute(
|
||||
xmlrpc_c::paramList const& paramList,
|
||||
RequestAttributes& att)
|
||||
{
|
||||
int group_id = xmlrpc_c::value_int(paramList.getInt(1));
|
||||
int user_id = xmlrpc_c::value_int(paramList.getInt(2));
|
||||
|
||||
PoolObjectAuth group_perms;
|
||||
PoolObjectAuth user_perms;
|
||||
|
||||
string group_name;
|
||||
string user_name;
|
||||
string error_str;
|
||||
|
||||
Group* group;
|
||||
|
||||
int rc;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Authorize the action
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
rc = get_info(pool, group_id, PoolObjectSQL::GROUP,
|
||||
att, group_perms, group_name, true);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rc = get_info(upool, user_id, PoolObjectSQL::USER, att, user_perms,
|
||||
user_name, false);
|
||||
|
||||
if ( rc == -1 )
|
||||
{
|
||||
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::USER),
|
||||
user_id), att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( att.uid != 0 )
|
||||
{
|
||||
AuthRequest ar(att.uid, att.group_ids);
|
||||
|
||||
ar.add_auth(AuthRequest::ADMIN, group_perms); // MANAGE GROUP
|
||||
|
||||
ar.add_auth(AuthRequest::ADMIN, user_perms); // MANAGE USER
|
||||
|
||||
if (UserPool::authorize(ar) == -1)
|
||||
{
|
||||
failure_response(AUTHORIZATION,
|
||||
authorization_error(ar.message, att),
|
||||
att);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
group = static_cast<GroupPool*>(pool)->get(group_id, true);
|
||||
|
||||
if ( group == 0 )
|
||||
{
|
||||
failure_response(NO_EXISTS,
|
||||
get_error(object_name(auth_object),group_id),
|
||||
att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rc = edit_admin(group, user_id, error_str);
|
||||
|
||||
if (rc == 0)
|
||||
{
|
||||
pool->update(group);
|
||||
}
|
||||
|
||||
group->unlock();
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
failure_response(INTERNAL,
|
||||
request_error("Cannot edit group", error_str),
|
||||
att);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
success_response(group_id, att);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int GroupAddAdmin::edit_admin(Group* group, int user_id, string& error_msg)
|
||||
{
|
||||
return group->add_admin(user_id, error_msg);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
int GroupDelAdmin::edit_admin(Group* group, int user_id, string& error_msg)
|
||||
{
|
||||
return group->del_admin(user_id, error_msg);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
Loading…
x
Reference in New Issue
Block a user