[PATCH] Return 403 Forbidden when user does not have permission to access kimchi

From: Aline Manera <alinefm@br.ibm.com> This patch **partial** fix bug #323. We still need to update UI to properly avoid user to perform some operations when he/she does not have enough permission to do it. Aline Manera (1): Return 403 Forbidden when user does not have permission to access kimchi po/en_US.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/kimchi.pot | 83 +++++++++++++++++++++++++++++++++++++++++-- po/pt_BR.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/zh_CN.po | 83 +++++++++++++++++++++++++++++++++++++++++-- src/kimchi/auth.py | 10 ++++-- src/kimchi/i18n.py | 1 + tests/test_authorization.py | 30 ++++++++-------- 7 files changed, 348 insertions(+), 25 deletions(-) -- 1.7.10.4

From: Aline Manera <alinefm@br.ibm.com> We need to differ when user is not logged into kimchi and when he does not have enough permissions to perform an operation. When user is not logged in, the UI needs to know to ask him to login again into kimchi. In this case, return 401 Unauthorized When user does not have enough permission returns 403 Forbidden 401 Unauthorized - The request requires user authentication. 403 Forbidden - The server understood the request, but is refusing to fulfill it. For reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html Also, updated the tests cases to reflect those changes and po files as new messages were added. Signed-off-by: Aline Manera <alinefm@br.ibm.com> --- po/en_US.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/kimchi.pot | 83 +++++++++++++++++++++++++++++++++++++++++-- po/pt_BR.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/zh_CN.po | 83 +++++++++++++++++++++++++++++++++++++++++-- src/kimchi/auth.py | 10 ++++-- src/kimchi/i18n.py | 1 + tests/test_authorization.py | 30 ++++++++-------- 7 files changed, 348 insertions(+), 25 deletions(-) diff --git a/po/en_US.po b/po/en_US.po index 8b9e3ca..8ac59c7 100644 --- a/po/en_US.po +++ b/po/en_US.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: kimchi 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-14 16:23-0200\n" +"POT-Creation-Date: 2014-02-20 15:26-0300\n" "PO-Revision-Date: 2013-07-11 17:32-0400\n" "Last-Translator: Crístian Viana <vianac@linux.vnet.ibm.com>\n" "Language-Team: English\n" @@ -616,6 +616,9 @@ msgstr "" msgid "Specify %(item)s to login into Kimchi" msgstr "" +msgid "This operation is not allowed as you have restricted access to Kimchi." +msgstr "" + #, python-format msgid "Error while getting block devices. Details: %(err)s" msgstr "" @@ -669,7 +672,8 @@ msgstr "" msgid "Bad format while reading volume descriptor in ISO %(filename)s" msgstr "" -msgid "Virtual machine $(name)s already exists" +#, python-format +msgid "Virtual machine %(name)s already exists" msgstr "" #, python-format @@ -1046,6 +1050,18 @@ msgid "Specify name and type to create a Network" msgstr "" #, python-format +msgid "" +"Unable to delete network %(name)s. There are still some VMs linked to this " +"network." +msgstr "" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some VMs running linked to " +"this network." +msgstr "" + +#, python-format msgid "Debug report %(name)s does not exist" msgstr "" @@ -1153,3 +1169,66 @@ msgstr "" msgid "Do not support guest CDROM hot plug attachment" msgstr "" + +msgid "Repository ID must be one word only string." +msgstr "" + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "" + +msgid "Repository URL arguments must be string." +msgstr "" + +msgid "GPG key must be a URL pointing to the ASCII-armored file." +msgstr "" + +msgid "Repository name must be string." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s already exists." +msgstr "" + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not update repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s does not exists." +msgstr "" + +#, python-format +msgid "There is no disabled repository called %(repo_id)s." +msgstr "" + +#, python-format +msgid "There is no enabled repository called %(repo_id)s." +msgstr "" + +msgid "There are no parameters to update repository." +msgstr "" + +msgid "OS distro not supported." +msgstr "" + +msgid "There is no YUM configuration directory." +msgstr "" + +msgid "There are no parameters to create a new repo file." +msgstr "" + +#, python-format +msgid "Could not write repo file %(repo_file)s" +msgstr "" + +#, python-format +msgid "Could not remove repository %(repo_id)s." +msgstr "" diff --git a/po/kimchi.pot b/po/kimchi.pot index c507149..f7b33ee 100755 --- a/po/kimchi.pot +++ b/po/kimchi.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-14 16:23-0200\n" +"POT-Creation-Date: 2014-02-20 15:26-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -601,6 +601,9 @@ msgstr "" msgid "Specify %(item)s to login into Kimchi" msgstr "" +msgid "This operation is not allowed as you have restricted access to Kimchi." +msgstr "" + #, python-format msgid "Error while getting block devices. Details: %(err)s" msgstr "" @@ -654,7 +657,8 @@ msgstr "" msgid "Bad format while reading volume descriptor in ISO %(filename)s" msgstr "" -msgid "Virtual machine $(name)s already exists" +#, python-format +msgid "Virtual machine %(name)s already exists" msgstr "" #, python-format @@ -1031,6 +1035,18 @@ msgid "Specify name and type to create a Network" msgstr "" #, python-format +msgid "" +"Unable to delete network %(name)s. There are still some VMs linked to this " +"network." +msgstr "" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some VMs running linked to " +"this network." +msgstr "" + +#, python-format msgid "Debug report %(name)s does not exist" msgstr "" @@ -1138,3 +1154,66 @@ msgstr "" msgid "Do not support guest CDROM hot plug attachment" msgstr "" + +msgid "Repository ID must be one word only string." +msgstr "" + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "" + +msgid "Repository URL arguments must be string." +msgstr "" + +msgid "GPG key must be a URL pointing to the ASCII-armored file." +msgstr "" + +msgid "Repository name must be string." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s already exists." +msgstr "" + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not update repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s does not exists." +msgstr "" + +#, python-format +msgid "There is no disabled repository called %(repo_id)s." +msgstr "" + +#, python-format +msgid "There is no enabled repository called %(repo_id)s." +msgstr "" + +msgid "There are no parameters to update repository." +msgstr "" + +msgid "OS distro not supported." +msgstr "" + +msgid "There is no YUM configuration directory." +msgstr "" + +msgid "There are no parameters to create a new repo file." +msgstr "" + +#, python-format +msgid "Could not write repo file %(repo_file)s" +msgstr "" + +#, python-format +msgid "Could not remove repository %(repo_id)s." +msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po index 6b45753..0d924e3 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: kimchi 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-14 16:23-0200\n" +"POT-Creation-Date: 2014-02-20 15:26-0300\n" "PO-Revision-Date: 2013-06-27 10:48+0000\n" "Last-Translator: Crístian Viana <vianac@linux.vnet.ibm.com>\n" "Language-Team: Aline Manera <alinefm@br.ibm.com>\n" @@ -631,6 +631,9 @@ msgstr "" msgid "Specify %(item)s to login into Kimchi" msgstr "" +msgid "This operation is not allowed as you have restricted access to Kimchi." +msgstr "" + #, python-format msgid "Error while getting block devices. Details: %(err)s" msgstr "" @@ -684,7 +687,8 @@ msgstr "" msgid "Bad format while reading volume descriptor in ISO %(filename)s" msgstr "" -msgid "Virtual machine $(name)s already exists" +#, python-format +msgid "Virtual machine %(name)s already exists" msgstr "" #, python-format @@ -1061,6 +1065,18 @@ msgid "Specify name and type to create a Network" msgstr "" #, python-format +msgid "" +"Unable to delete network %(name)s. There are still some VMs linked to this " +"network." +msgstr "" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some VMs running linked to " +"this network." +msgstr "" + +#, python-format msgid "Debug report %(name)s does not exist" msgstr "" @@ -1168,3 +1184,66 @@ msgstr "" msgid "Do not support guest CDROM hot plug attachment" msgstr "" + +msgid "Repository ID must be one word only string." +msgstr "" + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "" + +msgid "Repository URL arguments must be string." +msgstr "" + +msgid "GPG key must be a URL pointing to the ASCII-armored file." +msgstr "" + +msgid "Repository name must be string." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s already exists." +msgstr "" + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not update repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s does not exists." +msgstr "" + +#, python-format +msgid "There is no disabled repository called %(repo_id)s." +msgstr "" + +#, python-format +msgid "There is no enabled repository called %(repo_id)s." +msgstr "" + +msgid "There are no parameters to update repository." +msgstr "" + +msgid "OS distro not supported." +msgstr "" + +msgid "There is no YUM configuration directory." +msgstr "" + +msgid "There are no parameters to create a new repo file." +msgstr "" + +#, python-format +msgid "Could not write repo file %(repo_file)s" +msgstr "" + +#, python-format +msgid "Could not remove repository %(repo_id)s." +msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po index 9085b66..361c11a 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -20,7 +20,7 @@ msgid "" msgstr "" "Project-Id-Version: kimchi 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-02-14 16:23-0200\n" +"POT-Creation-Date: 2014-02-20 15:26-0300\n" "PO-Revision-Date: 2013-06-27 10:48+0000\n" "Last-Translator: ShaoHe Feng <shaohef@linux.vnet.ibm.com>\n" "Language-Team: ShaoHe Feng <shaohef@linux.vnet.ibm.com>\n" @@ -619,6 +619,9 @@ msgstr "" msgid "Specify %(item)s to login into Kimchi" msgstr "" +msgid "This operation is not allowed as you have restricted access to Kimchi." +msgstr "" + #, python-format msgid "Error while getting block devices. Details: %(err)s" msgstr "" @@ -672,7 +675,8 @@ msgstr "" msgid "Bad format while reading volume descriptor in ISO %(filename)s" msgstr "" -msgid "Virtual machine $(name)s already exists" +#, python-format +msgid "Virtual machine %(name)s already exists" msgstr "" #, python-format @@ -1049,6 +1053,18 @@ msgid "Specify name and type to create a Network" msgstr "" #, python-format +msgid "" +"Unable to delete network %(name)s. There are still some VMs linked to this " +"network." +msgstr "" + +#, python-format +msgid "" +"Unable to deactivate network %(name)s. There are some VMs running linked to " +"this network." +msgstr "" + +#, python-format msgid "Debug report %(name)s does not exist" msgstr "" @@ -1156,3 +1172,66 @@ msgstr "" msgid "Do not support guest CDROM hot plug attachment" msgstr "" + +msgid "Repository ID must be one word only string." +msgstr "" + +msgid "Repository URL must be an http://, ftp:// or file:// URL." +msgstr "" + +msgid "Repository URL arguments must be string." +msgstr "" + +msgid "GPG key must be a URL pointing to the ASCII-armored file." +msgstr "" + +msgid "Repository name must be string." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s already exists." +msgstr "" + +#, python-format +msgid "Could not enable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not disable repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Could not update repository %(repo_id)s." +msgstr "" + +#, python-format +msgid "Repository %(repo_id)s does not exists." +msgstr "" + +#, python-format +msgid "There is no disabled repository called %(repo_id)s." +msgstr "" + +#, python-format +msgid "There is no enabled repository called %(repo_id)s." +msgstr "" + +msgid "There are no parameters to update repository." +msgstr "" + +msgid "OS distro not supported." +msgstr "" + +msgid "There is no YUM configuration directory." +msgstr "" + +msgid "There are no parameters to create a new repo file." +msgstr "" + +#, python-format +msgid "Could not write repo file %(repo_file)s" +msgstr "" + +#, python-format +msgid "Could not remove repository %(repo_id)s." +msgstr "" diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py index ee572cb..94e7eab 100644 --- a/src/kimchi/auth.py +++ b/src/kimchi/auth.py @@ -197,10 +197,16 @@ def has_permission(admin_methods): def kimchiauth(admin_methods=None): debug("Entering kimchiauth...") - if check_auth_session() and has_permission(admin_methods): + if check_auth_session(): + if not has_permission(admin_methods): + e = InvalidOperation('KCHAUTH0004E') + raise cherrypy.HTTPError(403) return - if check_auth_httpba() and has_permission(admin_methods): + if check_auth_httpba(): + if not has_permission(admin_methods): + e = InvalidOperation('KCHAUTH0004E') + raise cherrypy.HTTPError(403) return if not from_browser(): diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py index a8d2f29..7d08254 100644 --- a/src/kimchi/i18n.py +++ b/src/kimchi/i18n.py @@ -39,6 +39,7 @@ messages = { "KCHAUTH0001E": _("Authentication failed for user '%(userid)s'. [Error code: %(code)s]"), "KCHAUTH0002E": _("You are not authorized to access Kimchi"), "KCHAUTH0003E": _("Specify %(item)s to login into Kimchi"), + "KCHAUTH0004E": _("This operation is not allowed as you have restricted access to Kimchi."), "KCHDISKS0001E": _("Error while getting block devices. Details: %(err)s"), "KCHDISKS0002E": _("Error while getting block device information for %(device)s."), diff --git a/tests/test_authorization.py b/tests/test_authorization.py index 7f939a8..24ce4bd 100644 --- a/tests/test_authorization.py +++ b/tests/test_authorization.py @@ -71,35 +71,35 @@ class AuthorizationTests(unittest.TestCase): # Non-root users can not reboot/shutdown host system resp = self.request('/host/reboot', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/host/shutdown', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) # Non-root users can not get or debug reports resp = self.request('/debugreports', '{}', 'GET') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/debugreports', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) # Non-root users can not create or delete network (only get) resp = self.request('/networks', '{}', 'GET') self.assertEquals(200, resp.status) resp = self.request('/networks', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/networks/default/activate', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/networks/default', '{}', 'DELETE') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) # Non-root users can not create or delete storage pool (only get) resp = self.request('/storagepools', '{}', 'GET') self.assertEquals(200, resp.status) resp = self.request('/storagepools', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/storagepools/default/activate', '{}', 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/storagepools/default', '{}', 'DELETE') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) # Non-root users can not update or delete a template # but he can get and create a new one @@ -109,16 +109,16 @@ class AuthorizationTests(unittest.TestCase): resp = self.request('/templates', req, 'POST') self.assertEquals(201, resp.status) resp = self.request('/templates/test', '{}', 'PUT') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/templates/test', '{}', 'DELETE') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) # Non-root users can only get vms resp = self.request('/vms', '{}', 'GET') self.assertEquals(200, resp.status) resp = self.request('/vms', req, 'POST') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/vms', '{}', 'PUT') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) resp = self.request('/vms', '{}', 'DELETE') - self.assertEquals(401, resp.status) + self.assertEquals(403, resp.status) -- 1.7.10.4

There are a lot of "#, python-format" comments in the .po files. Are they supposed to be there?

Reviewed-by: Crístian Viana Am 20-02-2014 15:39, schrieb Aline Manera:
From: Aline Manera <alinefm@br.ibm.com>
We need to differ when user is not logged into kimchi and when he does not have enough permissions to perform an operation. When user is not logged in, the UI needs to know to ask him to login again into kimchi. In this case, return 401 Unauthorized When user does not have enough permission returns 403 Forbidden
401 Unauthorized - The request requires user authentication. 403 Forbidden - The server understood the request, but is refusing to fulfill it.
For reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Also, updated the tests cases to reflect those changes and po files as new messages were added.
Signed-off-by: Aline Manera <alinefm@br.ibm.com>

Tested-By Christy Perez <christy@linux.vnet.ibm.com> OS: RHEL 6.4 I can now log in as a non-root user with no sudo privileges, and try to perform restricted actions (based on messages included in this patch). The actions just look like no-ops, and I see a 403 page returned in the kimchid output. So, I think this is working as intended and just needs the UI to return the appropriate permission denied error. On Thu, 2014-02-20 at 15:39 -0300, Aline Manera wrote:
From: Aline Manera <alinefm@br.ibm.com>
This patch **partial** fix bug #323.
We still need to update UI to properly avoid user to perform some operations when he/she does not have enough permission to do it.
Aline Manera (1): Return 403 Forbidden when user does not have permission to access kimchi
po/en_US.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/kimchi.pot | 83 +++++++++++++++++++++++++++++++++++++++++-- po/pt_BR.po | 83 +++++++++++++++++++++++++++++++++++++++++-- po/zh_CN.po | 83 +++++++++++++++++++++++++++++++++++++++++-- src/kimchi/auth.py | 10 ++++-- src/kimchi/i18n.py | 1 + tests/test_authorization.py | 30 ++++++++-------- 7 files changed, 348 insertions(+), 25 deletions(-)
participants (3)
-
Aline Manera
-
Christy Perez
-
Crístian Viana