Commit 0eb466b7 authored by Philipp Schafft's avatar Philipp Schafft 🦁

Feature: Allow mangement of <role>s via admin/ interface.

This allows to manage <role>s via admin interface if the role supports.
Also format of admin/manageauth has been changed:
- <source> was renamed to <role>.
- mount parameter was removed.
- <role> got new parameters: type, name,
  can-adduser, can-deleteuser, can-listuser.
- can-* parameters are bools ("true" or "false"). They should be used
  to show or hide elements on the admin interface.

Ticket #2123 is nearly complet with this, just admin/manageauth.xsl
needs up be updated. Please close the bug in the commit that updates
admin/manageauth.xsl.
See #2123
parent a9907569
...@@ -152,8 +152,8 @@ static const admin_command_t commands[] = { ...@@ -152,8 +152,8 @@ static const admin_command_t commands[] = {
{COMMAND_TRANSFORMED_KILL_CLIENT, KILLCLIENT_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED}, {COMMAND_TRANSFORMED_KILL_CLIENT, KILLCLIENT_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
{COMMAND_RAW_KILL_SOURCE, KILLSOURCE_RAW_REQUEST, ADMINTYPE_MOUNT, RAW}, {COMMAND_RAW_KILL_SOURCE, KILLSOURCE_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
{COMMAND_TRANSFORMED_KILL_SOURCE, KILLSOURCE_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED}, {COMMAND_TRANSFORMED_KILL_SOURCE, KILLSOURCE_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
{COMMAND_RAW_MANAGEAUTH, MANAGEAUTH_RAW_REQUEST, ADMINTYPE_MOUNT, RAW}, {COMMAND_RAW_MANAGEAUTH, MANAGEAUTH_RAW_REQUEST, ADMINTYPE_GENERAL, RAW},
{COMMAND_TRANSFORMED_MANAGEAUTH, MANAGEAUTH_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED}, {COMMAND_TRANSFORMED_MANAGEAUTH, MANAGEAUTH_TRANSFORMED_REQUEST, ADMINTYPE_GENERAL, TRANSFORMED},
{COMMAND_RAW_UPDATEMETADATA, UPDATEMETADATA_RAW_REQUEST, ADMINTYPE_MOUNT, RAW}, {COMMAND_RAW_UPDATEMETADATA, UPDATEMETADATA_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
{COMMAND_TRANSFORMED_UPDATEMETADATA, UPDATEMETADATA_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED}, {COMMAND_TRANSFORMED_UPDATEMETADATA, UPDATEMETADATA_TRANSFORMED_REQUEST, ADMINTYPE_MOUNT, TRANSFORMED},
{COMMAND_BUILDM3U, BUILDM3U_RAW_REQUEST, ADMINTYPE_MOUNT, RAW}, {COMMAND_BUILDM3U, BUILDM3U_RAW_REQUEST, ADMINTYPE_MOUNT, RAW},
...@@ -197,8 +197,7 @@ static void command_queue_reload(client_t *client, int response); ...@@ -197,8 +197,7 @@ static void command_queue_reload(client_t *client, int response);
static void command_list_mounts(client_t *client, int response); static void command_list_mounts(client_t *client, int response);
static void command_kill_client(client_t *client, source_t *source, static void command_kill_client(client_t *client, source_t *source,
int response); int response);
static void command_manageauth(client_t *client, source_t *source, static void command_manageauth(client_t *client, int response);
int response);
static void command_buildm3u(client_t *client, const char *mount); static void command_buildm3u(client_t *client, const char *mount);
static void command_kill_source(client_t *client, source_t *source, static void command_kill_source(client_t *client, source_t *source,
int response); int response);
...@@ -486,6 +485,12 @@ static void admin_handle_general_request(client_t *client) ...@@ -486,6 +485,12 @@ static void admin_handle_general_request(client_t *client)
case COMMAND_TRANSFORMED_MOVE_CLIENTS: case COMMAND_TRANSFORMED_MOVE_CLIENTS:
command_list_mounts(client, TRANSFORMED); command_list_mounts(client, TRANSFORMED);
break; break;
case COMMAND_TRANSFORMED_MANAGEAUTH:
command_manageauth(client, TRANSFORMED);
break;
case COMMAND_RAW_MANAGEAUTH:
command_manageauth(client, RAW);
break;
default: default:
ICECAST_LOG_WARN("General admin request not recognised"); ICECAST_LOG_WARN("General admin request not recognised");
client_send_error(client, 400, 0, "Unknown admin request"); client_send_error(client, 400, 0, "Unknown admin request");
...@@ -540,12 +545,6 @@ static void admin_handle_mount_request(client_t *client, source_t *source) { ...@@ -540,12 +545,6 @@ static void admin_handle_mount_request(client_t *client, source_t *source) {
case COMMAND_TRANSFORMED_KILL_SOURCE: case COMMAND_TRANSFORMED_KILL_SOURCE:
command_kill_source(client, source, TRANSFORMED); command_kill_source(client, source, TRANSFORMED);
break; break;
case COMMAND_TRANSFORMED_MANAGEAUTH:
command_manageauth(client, source, TRANSFORMED);
break;
case COMMAND_RAW_MANAGEAUTH:
command_manageauth(client, source, RAW);
break;
case COMMAND_TRANSFORMED_UPDATEMETADATA: case COMMAND_TRANSFORMED_UPDATEMETADATA:
command_updatemetadata(client, source, TRANSFORMED); command_updatemetadata(client, source, TRANSFORMED);
break; break;
...@@ -777,35 +776,51 @@ static void command_buildm3u(client_t *client, const char *mount) ...@@ -777,35 +776,51 @@ static void command_buildm3u(client_t *client, const char *mount)
} }
static void command_manageauth(client_t *client, source_t *source, static void command_manageauth(client_t *client, int response) {
int response)
{
xmlDocPtr doc; xmlDocPtr doc;
xmlNodePtr node, srcnode, msgnode; xmlNodePtr node, rolenode, usersnode, msgnode;
const char *action = NULL; const char *action = NULL;
const char *username = NULL; const char *username = NULL;
const char *idstring = NULL;
char *message = NULL; char *message = NULL;
int ret = AUTH_OK; int ret = AUTH_OK;
ice_config_t *config = config_get_config (); int error_code = 400;
mount_proxy *mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); const char *error_message = "missing parameter";
long unsigned int id;
ice_config_t *config = config_get_config();
auth_t *auth; auth_t *auth;
char idbuf[32];
do do
{ {
#if 0 /* get id */
if (mountinfo == NULL || mountinfo->auth == NULL) COMMAND_REQUIRE(client, "id", idstring);
{ id = atol(idstring);
ICECAST_LOG_WARN("manage auth request for %s but no facility available", source->mount);
/* no find a auth_t for that id by looking up the config */
/* globals first */
auth = auth_stack_getbyid(config->authstack, id);
/* now mounts */
if (!auth) {
mount_proxy *mount = config->mounts;
while (mount) {
auth = auth_stack_getbyid(mount->authstack, id);
if (auth)
break;
mount = mount->next;
}
}
/* check if we found one */
if (auth == NULL) {
ICECAST_LOG_WARN("Client requested mangement for unknown role %lu", id);
error_code = 404;
error_message = "Role not found";
break; break;
} }
auth = mountinfo->auth;
#else
ICECAST_LOG_WARN("manage auth request for %s but no facility available", source->mount);
break;
#endif
COMMAND_OPTIONAL(client, "action", action); COMMAND_OPTIONAL(client, "action", action);
COMMAND_OPTIONAL (client, "username", username); COMMAND_OPTIONAL(client, "username", username);
if (action == NULL) if (action == NULL)
action = "list"; action = "list";
...@@ -815,42 +830,60 @@ static void command_manageauth(client_t *client, source_t *source, ...@@ -815,42 +830,60 @@ static void command_manageauth(client_t *client, source_t *source,
const char *password = NULL; const char *password = NULL;
COMMAND_OPTIONAL(client, "password", password); COMMAND_OPTIONAL(client, "password", password);
if (username == NULL || password == NULL) if (username == NULL || password == NULL) {
{ ICECAST_LOG_WARN("manage auth request add for %lu but no user/pass", id);
ICECAST_LOG_WARN("manage auth request add for %s but no user/pass", source->mount);
break; break;
} }
if (!auth->adduser) {
error_message = "Adding users to role not supported by role";
break;
}
ret = auth->adduser(auth, username, password); ret = auth->adduser(auth, username, password);
if (ret == AUTH_FAILED) { if (ret == AUTH_FAILED) {
message = strdup("User add failed - check the icecast error log"); message = strdup("User add failed - check the icecast error log");
} } else if (ret == AUTH_USERADDED) {
if (ret == AUTH_USERADDED) {
message = strdup("User added"); message = strdup("User added");
} } else if (ret == AUTH_USEREXISTS) {
if (ret == AUTH_USEREXISTS) {
message = strdup("User already exists - not added"); message = strdup("User already exists - not added");
} }
} }
if (!strcmp(action, "delete")) if (!strcmp(action, "delete"))
{ {
if (username == NULL) if (username == NULL) {
{ ICECAST_LOG_WARN("manage auth request delete for %lu but no username", id);
ICECAST_LOG_WARN("manage auth request delete for %s but no username", source->mount); break;
}
if (!auth->deleteuser) {
error_message = "Deleting users from role not supported by role";
break; break;
} }
ret = auth->deleteuser(auth, username); ret = auth->deleteuser(auth, username);
if (ret == AUTH_FAILED) { if (ret == AUTH_FAILED) {
message = strdup("User delete failed - check the icecast error log"); message = strdup("User delete failed - check the icecast error log");
} } else if (ret == AUTH_USERDELETED) {
if (ret == AUTH_USERDELETED) {
message = strdup("User deleted"); message = strdup("User deleted");
} }
} }
doc = xmlNewDoc(XMLSTR("1.0")); doc = xmlNewDoc(XMLSTR("1.0"));
node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL); node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL); rolenode = xmlNewChild(node, NULL, XMLSTR("role"), NULL);
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
snprintf(idbuf, sizeof(idbuf), "%lu", auth->id);
xmlSetProp(rolenode, XMLSTR("id"), XMLSTR(idbuf));
if (auth->type)
xmlSetProp(rolenode, XMLSTR("type"), XMLSTR(auth->type));
if (auth->role)
xmlSetProp(rolenode, XMLSTR("name"), XMLSTR(auth->role));
xmlSetProp(rolenode, XMLSTR("can-adduser"), XMLSTR(auth->adduser ? "true" : "false"));
xmlSetProp(rolenode, XMLSTR("can-deleteuser"), XMLSTR(auth->deleteuser ? "true" : "false"));
xmlSetProp(rolenode, XMLSTR("can-listuser"), XMLSTR(auth->listuser ? "true" : "false"));
if (message) { if (message) {
msgnode = xmlNewChild(node, NULL, XMLSTR("iceresponse"), NULL); msgnode = xmlNewChild(node, NULL, XMLSTR("iceresponse"), NULL);
...@@ -859,10 +892,13 @@ static void command_manageauth(client_t *client, source_t *source, ...@@ -859,10 +892,13 @@ static void command_manageauth(client_t *client, source_t *source,
xmlDocSetRootElement(doc, node); xmlDocSetRootElement(doc, node);
if (auth && auth->listuser) if (auth && auth->listuser) {
auth->listuser(auth, srcnode); usersnode = xmlNewChild(rolenode, NULL, XMLSTR("users"), NULL);
auth->listuser(auth, usersnode);
}
config_release_config (); config_release_config();
auth_release(auth);
admin_send_response(doc, client, response, admin_send_response(doc, client, response,
MANAGEAUTH_TRANSFORMED_REQUEST); MANAGEAUTH_TRANSFORMED_REQUEST);
...@@ -871,8 +907,9 @@ static void command_manageauth(client_t *client, source_t *source, ...@@ -871,8 +907,9 @@ static void command_manageauth(client_t *client, source_t *source,
return; return;
} while (0); } while (0);
config_release_config (); config_release_config();
client_send_error(client, 400, 0, "missing parameter"); auth_release(auth);
client_send_error(client, error_code, 0, error_message);
} }
static void command_kill_source(client_t *client, source_t *source, static void command_kill_source(client_t *client, source_t *source,
......
...@@ -691,6 +691,31 @@ auth_t *auth_stack_get(auth_stack_t *stack) { ...@@ -691,6 +691,31 @@ auth_t *auth_stack_get(auth_stack_t *stack) {
return auth; return auth;
} }
auth_t *auth_stack_getbyid(auth_stack_t *stack, unsigned long id) {
auth_t *ret = NULL;
if (!stack)
return NULL;
auth_stack_addref(stack);
while (!ret && stack) {
auth_t *auth = auth_stack_get(stack);
if (auth->id == id) {
ret = auth;
break;
}
auth_release(auth);
auth_stack_next(&stack);
}
if (stack)
auth_stack_release(stack);
return ret;
}
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack) { acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack) {
acl_t *ret = NULL; acl_t *ret = NULL;
......
...@@ -129,6 +129,7 @@ int auth_stack_next(auth_stack_t **stack); /* returns -1 on error, 0 o ...@@ -129,6 +129,7 @@ int auth_stack_next(auth_stack_t **stack); /* returns -1 on error, 0 o
int auth_stack_push(auth_stack_t **stack, auth_t *auth); int auth_stack_push(auth_stack_t **stack, auth_t *auth);
int auth_stack_append(auth_stack_t *stack, auth_stack_t *tail); int auth_stack_append(auth_stack_t *stack, auth_stack_t *tail);
auth_t *auth_stack_get(auth_stack_t *stack); auth_t *auth_stack_get(auth_stack_t *stack);
auth_t *auth_stack_getbyid(auth_stack_t *stack, unsigned long id);
acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack); acl_t *auth_stack_get_anonymous_acl(auth_stack_t *stack);
#endif #endif
...@@ -398,7 +398,7 @@ static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode) ...@@ -398,7 +398,7 @@ static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode)
while (node) while (node)
{ {
htpasswd_user *user = (htpasswd_user *)node->key; htpasswd_user *user = (htpasswd_user *)node->key;
newnode = xmlNewChild (srcnode, NULL, XMLSTR("User"), NULL); newnode = xmlNewChild (srcnode, NULL, XMLSTR("user"), NULL);
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name)); xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(user->name));
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(user->pass)); xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(user->pass));
node = avl_get_next (node); node = avl_get_next (node);
......
...@@ -61,7 +61,7 @@ static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode) { ...@@ -61,7 +61,7 @@ static auth_result static_userlist(auth_t *auth, xmlNodePtr srcnode) {
auth_static_t *auth_info = auth->state; auth_static_t *auth_info = auth->state;
xmlNodePtr newnode; xmlNodePtr newnode;
newnode = xmlNewChild(srcnode, NULL, XMLSTR("User"), NULL); newnode = xmlNewChild(srcnode, NULL, XMLSTR("user"), NULL);
xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(auth_info->username)); xmlNewChild(newnode, NULL, XMLSTR("username"), XMLSTR(auth_info->username));
xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(auth_info->password)); xmlNewChild(newnode, NULL, XMLSTR("password"), XMLSTR(auth_info->password));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment