permissions: expose new view that lists all available views for usage in whitelist access.
This commit is contained in:
parent
8bfe9e6306
commit
dc2af71072
7 changed files with 147 additions and 21 deletions
|
|
@ -201,22 +201,21 @@ rss_include_diff = false
|
|||
## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
|
||||
gist_alias_url =
|
||||
|
||||
## List of controllers (using glob pattern syntax) that AUTH TOKENS could be
|
||||
## List of views (using glob pattern syntax) that AUTH TOKENS could be
|
||||
## used for access.
|
||||
## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
|
||||
## came from the the logged in user who own this authentication token.
|
||||
##
|
||||
## Syntax is ControllerClass:function_pattern.
|
||||
## To enable access to raw_files put `FilesController:raw`.
|
||||
## To enable access to patches add `ChangesetController:changeset_patch`.
|
||||
## list of all views can be found under `_admin/permissions/auth_token_access`
|
||||
## The list should be "," separated and on a single line.
|
||||
##
|
||||
## Recommended controllers to enable:
|
||||
# ChangesetController:changeset_patch,
|
||||
# ChangesetController:changeset_raw,
|
||||
# FilesController:raw,
|
||||
# FilesController:archivefile,
|
||||
# GistsController:*,
|
||||
## Most common views to enable:
|
||||
# ChangesetController:changeset_patch
|
||||
# ChangesetController:changeset_raw
|
||||
# RepoFilesView.repo_files_diff
|
||||
# RepoFilesView.repo_archivefile
|
||||
# RepoFilesView.repo_file_raw
|
||||
# GistView:*
|
||||
api_access_controllers_whitelist =
|
||||
|
||||
## default encoding used to convert from and to unicode
|
||||
|
|
|
|||
|
|
@ -175,22 +175,21 @@ rss_include_diff = false
|
|||
## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/{gistid}
|
||||
gist_alias_url =
|
||||
|
||||
## List of controllers (using glob pattern syntax) that AUTH TOKENS could be
|
||||
## List of views (using glob pattern syntax) that AUTH TOKENS could be
|
||||
## used for access.
|
||||
## Adding ?auth_token=TOKEN_HASH to the url authenticates this request as if it
|
||||
## came from the the logged in user who own this authentication token.
|
||||
##
|
||||
## Syntax is ControllerClass:function_pattern.
|
||||
## To enable access to raw_files put `FilesController:raw`.
|
||||
## To enable access to patches add `ChangesetController:changeset_patch`.
|
||||
## list of all views can be found under `_admin/permissions/auth_token_access`
|
||||
## The list should be "," separated and on a single line.
|
||||
##
|
||||
## Recommended controllers to enable:
|
||||
# ChangesetController:changeset_patch,
|
||||
# ChangesetController:changeset_raw,
|
||||
# FilesController:raw,
|
||||
# FilesController:archivefile,
|
||||
# GistsController:*,
|
||||
## Most common views to enable:
|
||||
# ChangesetController:changeset_patch
|
||||
# ChangesetController:changeset_raw
|
||||
# RepoFilesView.repo_files_diff
|
||||
# RepoFilesView.repo_archivefile
|
||||
# RepoFilesView.repo_file_raw
|
||||
# GistView:*
|
||||
api_access_controllers_whitelist =
|
||||
|
||||
## default encoding used to convert from and to unicode
|
||||
|
|
|
|||
|
|
@ -102,6 +102,10 @@ def admin_routes(config):
|
|||
name='admin_permissions_overview',
|
||||
pattern='/permissions/overview')
|
||||
|
||||
config.add_route(
|
||||
name='admin_permissions_auth_token_access',
|
||||
pattern='/permissions/auth_token_access')
|
||||
|
||||
# users admin
|
||||
config.add_route(
|
||||
name='users',
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import re
|
||||
import logging
|
||||
import formencode
|
||||
from pyramid.interfaces import IRoutesMapper
|
||||
|
||||
from pyramid.view import view_config
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
|
|
@ -31,6 +33,7 @@ from rhodecode.apps._base import BaseAppView
|
|||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.lib.auth import (
|
||||
LoginRequired, HasPermissionAllDecorator, CSRFRequired)
|
||||
from rhodecode.lib.utils2 import aslist
|
||||
from rhodecode.model.db import User, UserIpMap
|
||||
from rhodecode.model.forms import (
|
||||
ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm)
|
||||
|
|
@ -308,3 +311,59 @@ class AdminPermissionsView(BaseAppView):
|
|||
c.user = User.get_default_user(refresh=True)
|
||||
c.perm_user = c.user.AuthUser
|
||||
return self._get_template_context(c)
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAllDecorator('hg.admin')
|
||||
@view_config(
|
||||
route_name='admin_permissions_auth_token_access', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/permissions/permissions.mako')
|
||||
def auth_token_access(self):
|
||||
from rhodecode import CONFIG
|
||||
|
||||
c = self.load_default_context()
|
||||
c.active = 'auth_token_access'
|
||||
|
||||
c.user = User.get_default_user(refresh=True)
|
||||
c.perm_user = c.user.AuthUser
|
||||
|
||||
mapper = self.request.registry.queryUtility(IRoutesMapper)
|
||||
c.view_data = []
|
||||
|
||||
_argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
|
||||
introspector = self.request.registry.introspector
|
||||
|
||||
view_intr = {}
|
||||
for view_data in introspector.get_category('views'):
|
||||
intr = view_data['introspectable']
|
||||
|
||||
if 'route_name' in intr and intr['attr']:
|
||||
view_intr[intr['route_name']] = '{}.{}'.format(
|
||||
str(intr['derived_callable'].func_name), intr['attr']
|
||||
)
|
||||
|
||||
c.whitelist_key = 'api_access_controllers_whitelist'
|
||||
c.whitelist_file = CONFIG.get('__file__')
|
||||
whitelist_views = aslist(
|
||||
CONFIG.get(c.whitelist_key), sep=',')
|
||||
|
||||
for route_info in mapper.get_routes():
|
||||
if not route_info.name.startswith('__'):
|
||||
routepath = route_info.pattern
|
||||
|
||||
def replace(matchobj):
|
||||
if matchobj.group(1):
|
||||
return "{%s}" % matchobj.group(1).split(':')[0]
|
||||
else:
|
||||
return "{%s}" % matchobj.group(2)
|
||||
|
||||
routepath = _argument_prog.sub(replace, routepath)
|
||||
|
||||
if not routepath.startswith('/'):
|
||||
routepath = '/' + routepath
|
||||
|
||||
view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE')
|
||||
active = view_fqn in whitelist_views
|
||||
c.view_data.append((route_info.name, view_fqn, routepath, active))
|
||||
|
||||
c.whitelist_views = whitelist_views
|
||||
return self._get_template_context(c)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ function registerRCRoutes() {
|
|||
pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
|
||||
pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
|
||||
pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
|
||||
pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
|
||||
pyroutes.register('users', '/_admin/users', []);
|
||||
pyroutes.register('users_data', '/_admin/users_data', []);
|
||||
pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
|
||||
|
|
@ -176,7 +177,7 @@ function registerRCRoutes() {
|
|||
pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
|
||||
pyroutes.register('my_account_update', '/_admin/my_account/update', []);
|
||||
pyroutes.register('my_account_password', '/_admin/my_account/password', []);
|
||||
pyroutes.register('my_account_password_update', '/_admin/my_account/password', []);
|
||||
pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
|
||||
pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
|
||||
pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
|
||||
pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@
|
|||
<li class="${'active' if c.active=='ips' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='auth_token_access' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_auth_token_access')}">${_('AuthToken Access')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='perms' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_overview')}">${_('Overview')}</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('View whitelist')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="">
|
||||
|
||||
<p class="pr-description">
|
||||
View white list defines a set of views that can be accessed using auth token without the need to login.
|
||||
Adding ?auth_token = SECRET_TOKEN to the url authenticates this request as if it
|
||||
came from the the logged in user who owns this authentication token.
|
||||
|
||||
E.g. adding `RepoFilesView.repo_file_raw` allows to access a raw diff using such url:
|
||||
http[s]://server.com/{repo_name}/raw/{commit_id}/{file_path}?auth_token=SECRET_TOKEN
|
||||
|
||||
White list can be defined inside `${c.whitelist_file}` under `${c.whitelist_key}=` setting
|
||||
|
||||
Currently under this settings following views are set:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
% for entry in c.whitelist_views:
|
||||
${entry}
|
||||
% endfor
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('List of views available for usage in whitelist access')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="">
|
||||
|
||||
|
||||
<table class="rctable ip-whitelist">
|
||||
<tr>
|
||||
<th>Active</th>
|
||||
<th>View FQN</th>
|
||||
<th>URL pattern</th>
|
||||
</tr>
|
||||
|
||||
% for route_name, view_fqn, view_url, active in c.view_data:
|
||||
<tr>
|
||||
<td class="td-x">${h.bool2icon(active)}</td>
|
||||
<td class="td-x">${view_fqn}</td>
|
||||
<td class="td-x" title="${route_name}">${view_url}</td>
|
||||
</tr>
|
||||
% endfor
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue