From f9a9d2bb63a14b9fc583ceb96e937803e3008cd8 Mon Sep 17 00:00:00 2001 From: Dennis Oelkers Date: Tue, 7 Mar 2017 15:58:09 +0100 Subject: [PATCH] Properly escape username/roles in web interface (#3588) * Escaping username component to allow usernames with slash. * Allowing to handle deletion/updates of roles with special characters. * Allowing editing/updating/deleting users with special characters in name * Using proper route methods, escaping username in CurrentUserStore. Fixes #3569 (cherry picked from commit 34446c2e05483e16687f7ff230321eef7d58823f / PR #3570) --- .../authentication/AuthenticationComponent.jsx | 2 +- .../src/components/navigation/UserMenu.jsx | 2 +- .../src/components/users/UserList.jsx | 2 +- .../src/stores/users/CurrentUserStore.jsx | 12 +++++------- .../src/stores/users/RolesStore.ts | 6 +++--- .../src/stores/users/UsersStore.ts | 10 +++++----- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/graylog2-web-interface/src/components/authentication/AuthenticationComponent.jsx b/graylog2-web-interface/src/components/authentication/AuthenticationComponent.jsx index 14240c8e07ea..e2c1e6dfce1c 100644 --- a/graylog2-web-interface/src/components/authentication/AuthenticationComponent.jsx +++ b/graylog2-web-interface/src/components/authentication/AuthenticationComponent.jsx @@ -118,7 +118,7 @@ const AuthenticationComponent = React.createClass({ if (authenticators.length === 0) { // special case, this is a user editing their own profile - authenticators = [ + authenticators = [ Edit User ]; } diff --git a/graylog2-web-interface/src/components/navigation/UserMenu.jsx b/graylog2-web-interface/src/components/navigation/UserMenu.jsx index 0a02148bce04..48518eda5049 100644 --- a/graylog2-web-interface/src/components/navigation/UserMenu.jsx +++ b/graylog2-web-interface/src/components/navigation/UserMenu.jsx @@ -24,7 +24,7 @@ const UserMenu = React.createClass({ render() { return ( - + Edit profile diff --git a/graylog2-web-interface/src/components/users/UserList.jsx b/graylog2-web-interface/src/components/users/UserList.jsx index 364b51694ea9..5349c3ccdb69 100644 --- a/graylog2-web-interface/src/components/users/UserList.jsx +++ b/graylog2-web-interface/src/components/users/UserList.jsx @@ -126,7 +126,7 @@ const UserList = React.createClass({ ); const editAction = ( - + diff --git a/graylog2-web-interface/src/stores/users/CurrentUserStore.jsx b/graylog2-web-interface/src/stores/users/CurrentUserStore.jsx index 9ba18612cb48..41eb0fe022ef 100644 --- a/graylog2-web-interface/src/stores/users/CurrentUserStore.jsx +++ b/graylog2-web-interface/src/stores/users/CurrentUserStore.jsx @@ -2,17 +2,15 @@ import Reflux from 'reflux'; import URLUtils from 'util/URLUtils'; import fetch from 'logic/rest/FetchProvider'; +import ApiRoutes from 'routing/ApiRoutes'; -import StoreProvider from 'injection/StoreProvider'; -const SessionStore = StoreProvider.getStore('Session'); -const StartpageStore = StoreProvider.getStore('Startpage'); +import CombinedProvider from 'injection/CombinedProvider'; -import ActionsProvider from 'injection/ActionsProvider'; -const SessionActions = ActionsProvider.getActions('Session'); +const { SessionStore, SessionActions } = CombinedProvider.get('Session'); +const { StartpageStore } = CombinedProvider.get('Startpage'); const CurrentUserStore = Reflux.createStore({ listenables: [SessionActions], - sourceUrl: '/users', currentUser: undefined, init() { @@ -45,7 +43,7 @@ const CurrentUserStore = Reflux.createStore({ }, update(username) { - fetch('GET', URLUtils.qualifyUrl(this.sourceUrl + '/' + username)) + fetch('GET', URLUtils.qualifyUrl(ApiRoutes.UsersApiController.load(encodeURIComponent(username)).url)) .then((resp) => { this.currentUser = resp; this.trigger({ currentUser: this.currentUser }); diff --git a/graylog2-web-interface/src/stores/users/RolesStore.ts b/graylog2-web-interface/src/stores/users/RolesStore.ts index 06ff18b7fb68..aaad119af98e 100644 --- a/graylog2-web-interface/src/stores/users/RolesStore.ts +++ b/graylog2-web-interface/src/stores/users/RolesStore.ts @@ -51,7 +51,7 @@ const RolesStore = { }, updateRole(rolename: string, role: Role): Promise { - const promise = fetch('PUT', URLUtils.qualifyUrl(ApiRoutes.RolesApiController.updateRole(rolename).url), role); + const promise = fetch('PUT', URLUtils.qualifyUrl(ApiRoutes.RolesApiController.updateRole(encodeURIComponent(rolename)).url), role); promise.then((newRole) => { UserNotification.success("Role \"" + newRole.name + "\" was updated successfully"); @@ -66,7 +66,7 @@ const RolesStore = { }, deleteRole(rolename: string): Promise { - const url = URLUtils.qualifyUrl(ApiRoutes.RolesApiController.deleteRole(rolename).url); + const url = URLUtils.qualifyUrl(ApiRoutes.RolesApiController.deleteRole(encodeURIComponent(rolename)).url); const promise = fetch('DELETE', url); promise.then(() => { @@ -80,7 +80,7 @@ const RolesStore = { return promise; }, getMembers(rolename: string): Promise { - const url = URLUtils.qualifyUrl(ApiRoutes.RolesApiController.loadMembers(rolename).url); + const url = URLUtils.qualifyUrl(ApiRoutes.RolesApiController.loadMembers(encodeURIComponent(rolename)).url); const promise = fetch('GET', url); promise.catch((error) => { if (error.additional.status !== 404) { diff --git a/graylog2-web-interface/src/stores/users/UsersStore.ts b/graylog2-web-interface/src/stores/users/UsersStore.ts index 5c68d8272f44..e550ac48e368 100644 --- a/graylog2-web-interface/src/stores/users/UsersStore.ts +++ b/graylog2-web-interface/src/stores/users/UsersStore.ts @@ -58,7 +58,7 @@ export const UsersStore = { }, load(username: string): Promise { - const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.load(username).url); + const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.load(encodeURIComponent(username)).url); const promise = fetch('GET', url); promise.catch((error) => { UserNotification.error("Loading user failed with status: " + error, @@ -69,7 +69,7 @@ export const UsersStore = { }, deleteUser(username: string): Promise { - const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.delete(username).url); + const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.delete(encodeURIComponent(username)).url); const promise = fetch('DELETE', url); promise.then(() => { @@ -85,21 +85,21 @@ export const UsersStore = { }, updateRoles(username: string, roles: string[]): void { - const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.update(username).url); + const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.update(encodeURIComponent(username)).url); const promise = fetch('PUT', url, {roles: roles}); return promise; }, changePassword(username: string, request: ChangePasswordRequest): void { - const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.changePassword(username).url); + const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.changePassword(encodeURIComponent(username)).url); const promise = fetch('PUT', url, request); return promise; }, update(username: string, request: any): void { - const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.update(username).url); + const url = URLUtils.qualifyUrl(ApiRoutes.UsersApiController.update(encodeURIComponent(username)).url); const promise = fetch('PUT', url, request); return promise;