1
0
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:
Carlos Martín 2015-02-02 15:38:42 +01:00
parent 614758b294
commit d294d96a52
6 changed files with 418 additions and 2 deletions

View File

@ -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)
// *************************************************************************

View File

@ -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:
/**

View File

@ -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);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */