Files
@ ee1da602b590
Branch filter:
Location: kallithea/kallithea/templates/admin/user_groups/user_group_edit_perms.html
ee1da602b590
5.9 KiB
text/html
repo_groups: fix deletion of subgroups
Deletion of a repository group that has a parent group (i.e. is not at the
root of the repository group tree) failed as follows:
Traceback (most recent call last):
[...]
File ".../lib/python3.9/site-packages/tg/configurator/components/dispatch.py", line 114, in _call_controller
return controller(*remainder, **params)
File "<decorator-gen-5>", line 2, in delete
File "/home/tdescham/repo/contrib/kallithea/kallithea-release/kallithea/lib/auth.py", line 572, in __wrapper
return func(*fargs, **fkwargs)
File "/home/tdescham/repo/contrib/kallithea/kallithea-release/kallithea/controllers/admin/repo_groups.py", line 271, in delete
if gr.parent_group:
File ".../lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 294, in __get__
return self.impl.get(instance_state(instance), dict_)
File ".../lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 730, in get
value = self.callable_(state, passive)
File ".../lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 717, in _load_for_state
raise orm_exc.DetachedInstanceError(
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <RepoGroup at 0x7f1f2664f4c0> is not bound to a Session; lazy load operation of attribute 'parent_group' cannot proceed (Background on this error at: http://sqlalche.me/e/13/bhk3)
In the reference 'gr.parent_group', 'gr' is an SQLAlchemy object referring
to the group being deleted, and 'gr.parent_group' is a lazy reference to its
parent group. The 'lazy' means that the parent group object is not loaded
automatically when 'gr' is assigned, but instead will be loaded on-the-fly
when the parent group is actually accessed. See [1] and [2] for more
information.
The problem was that the lazy 'parent_group' attribute was accessed _after_
deleting the database object it was part of.
Fix this by obtaining a handle to the parent group _before_ deleting the
subgroup.
Reported-by: André Klitzing (via mailing list)
[1] https://docs.sqlalchemy.org/en/13/errors.html#error-bhk3
[2] https://docs.sqlalchemy.org/en/13/orm/loading_relationships.html
Deletion of a repository group that has a parent group (i.e. is not at the
root of the repository group tree) failed as follows:
Traceback (most recent call last):
[...]
File ".../lib/python3.9/site-packages/tg/configurator/components/dispatch.py", line 114, in _call_controller
return controller(*remainder, **params)
File "<decorator-gen-5>", line 2, in delete
File "/home/tdescham/repo/contrib/kallithea/kallithea-release/kallithea/lib/auth.py", line 572, in __wrapper
return func(*fargs, **fkwargs)
File "/home/tdescham/repo/contrib/kallithea/kallithea-release/kallithea/controllers/admin/repo_groups.py", line 271, in delete
if gr.parent_group:
File ".../lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 294, in __get__
return self.impl.get(instance_state(instance), dict_)
File ".../lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 730, in get
value = self.callable_(state, passive)
File ".../lib/python3.9/site-packages/sqlalchemy/orm/strategies.py", line 717, in _load_for_state
raise orm_exc.DetachedInstanceError(
sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <RepoGroup at 0x7f1f2664f4c0> is not bound to a Session; lazy load operation of attribute 'parent_group' cannot proceed (Background on this error at: http://sqlalche.me/e/13/bhk3)
In the reference 'gr.parent_group', 'gr' is an SQLAlchemy object referring
to the group being deleted, and 'gr.parent_group' is a lazy reference to its
parent group. The 'lazy' means that the parent group object is not loaded
automatically when 'gr' is assigned, but instead will be loaded on-the-fly
when the parent group is actually accessed. See [1] and [2] for more
information.
The problem was that the lazy 'parent_group' attribute was accessed _after_
deleting the database object it was part of.
Fix this by obtaining a handle to the parent group _before_ deleting the
subgroup.
Reported-by: André Klitzing (via mailing list)
[1] https://docs.sqlalchemy.org/en/13/errors.html#error-bhk3
[2] https://docs.sqlalchemy.org/en/13/orm/loading_relationships.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | ${h.form(url('edit_user_group_perms_update', id=c.user_group.users_group_id))}
<div class="form">
<div>
<div>
<table id="permissions_manage" class="table">
<tr>
<td>${_('None')}</td>
<td>${_('Read')}</td>
<td>${_('Write')}</td>
<td>${_('Admin')}</td>
<td>${_('User/User Group')}</td>
<td></td>
</tr>
## USERS
%for r2p in c.user_group.user_user_group_to_perm:
##forbid revoking permission from yourself, except if you're an super admin
<tr id="id${id(r2p.user.username)}">
%if request.authuser.user_id != r2p.user.user_id or request.authuser.is_admin:
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.none')}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.read')}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.write')}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.admin')}</td>
<td>
${h.gravatar(r2p.user.email, cls="perm-gravatar", size=14)}
%if h.HasPermissionAny('hg.admin')() and r2p.user.username != 'default':
<a href="${h.url('edit_user',id=r2p.user.user_id)}">${r2p.user.username}</a>
%else:
${r2p.user.username if r2p.user.username != 'default' else _('Default')}
%endif
</td>
<td>
%if r2p.user.username !='default':
<button type="button" class="btn btn-default btn-xs" onclick="ajaxActionRevoke(${r2p.user.user_id}, 'user', '${'id%s'%id(r2p.user.username)}', '${r2p.user.username}')">
<i class="icon-minus-circled"></i>${_('Revoke')}
</button>
%endif
</td>
%else:
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.none', disabled="disabled")}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.read', disabled="disabled")}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.write', disabled="disabled")}</td>
<td>${h.radio('u_perm_%s' % r2p.user.username,'usergroup.admin', disabled="disabled")}</td>
<td>
${h.gravatar(r2p.user.email, cls="perm-gravatar", size=14)}
${r2p.user.username if r2p.user.username != 'default' else _('Default')}
</td>
<td><i class="icon-user"></i>${_('Admin')}</td>
%endif
</tr>
%endfor
## USER GROUPS
%for g2p in c.user_group.user_group_user_group_to_perm:
<tr id="id${id(g2p.user_group.users_group_name)}">
<td>${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.none')}</td>
<td>${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.read')}</td>
<td>${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.write')}</td>
<td>${h.radio('g_perm_%s' % g2p.user_group.users_group_name,'usergroup.admin')}</td>
<td>
<i class="icon-users"></i>
%if h.HasPermissionAny('hg.admin')():
<a href="${h.url('edit_users_group',id=g2p.user_group.users_group_id)}">
${g2p.user_group.users_group_name}
</a>
%else:
${g2p.user_group.users_group_name}
%endif
</td>
<td>
<button class="btn btn-default btn-xs" onclick="ajaxActionRevoke(${g2p.user_group.users_group_id}, 'user_group', '${'id%s'%id(g2p.user_group.users_group_name)}', '${g2p.user_group.users_group_name}')">
<i class="icon-minus-circled"></i>${_('Revoke')}
</button>
</td>
</tr>
%endfor
## New entries added by addPermAction here.
<tr class="new_members last_new_member" id="add_perm_input"><td colspan="6"></td></tr>
<tr>
<td colspan="6">
<button id="add_perm" class="btn btn-link btn-xs">
<i class="icon-plus"></i>${_('Add new')}
</button>
</td>
</tr>
</table>
</div>
<div class="buttons">
${h.submit('save',_('Save'),class_="btn btn-default")}
${h.reset('reset',_('Reset'),class_="btn btn-default")}
</div>
</div>
</div>
${h.end_form()}
<script>
'use strict';
function ajaxActionRevoke(obj_id, obj_type, field_id, obj_name) {
let url = ${h.js(h.url('edit_user_group_perms_delete', id=c.user_group.users_group_id))};
var revoke_msg = _TM['Confirm to revoke permission for {0}: {1}?'].format(obj_type.replace('_', ' '), obj_name);
if (confirm(revoke_msg)){
ajaxActionRevokePermission(url, obj_id, obj_type, field_id);
}
}
$(document).ready(function () {
if (!$('#perm_new_member_name').hasClass('error')) {
$('#add_perm_input').hide();
}
$('#add_perm').click(function () {
addPermAction('usergroup');
});
});
</script>
|