editSideTag API call
New API call for editing basic info on sidetags. Needs to be applied with proper policies. Fixes: https://pagure.io/koji/issue/1998
This commit is contained in:
parent
164e4bfb6e
commit
76352587fa
4 changed files with 94 additions and 19 deletions
|
|
@ -990,8 +990,11 @@ def _direct_pkglist_add(taginfo, pkginfo, owner, block, extra_arches, force,
|
||||||
action = 'block'
|
action = 'block'
|
||||||
if policy:
|
if policy:
|
||||||
context.session.assertLogin()
|
context.session.assertLogin()
|
||||||
policy_data = {'tag': tag_id, 'action': action, 'package': pkginfo, 'force': force}
|
policy_data = {'tag': tag_id, 'action': action, 'package': pkginfo,
|
||||||
assert_policy('package_list', policy_data, force=force)
|
'force' : force, 'extra': tag['extra']}
|
||||||
|
# don't check policy for admins using force
|
||||||
|
if not (force and context.session.hasPerm('admin')):
|
||||||
|
assert_policy('package_list', policy_data)
|
||||||
if not pkg:
|
if not pkg:
|
||||||
pkg = lookup_package(pkginfo, create=True)
|
pkg = lookup_package(pkginfo, create=True)
|
||||||
# validate arches before running callbacks
|
# validate arches before running callbacks
|
||||||
|
|
@ -1068,7 +1071,8 @@ def _direct_pkglist_remove(taginfo, pkginfo, force=False, policy=False):
|
||||||
pkg = lookup_package(pkginfo, strict=True)
|
pkg = lookup_package(pkginfo, strict=True)
|
||||||
if policy:
|
if policy:
|
||||||
context.session.assertLogin()
|
context.session.assertLogin()
|
||||||
policy_data = {'tag': tag['id'], 'action': 'remove', 'package': pkg['id'], 'force': force}
|
policy_data = {'tag': tag['id'], 'action': 'remove', 'package': pkg['id'],
|
||||||
|
'force' : force, 'extra': tag['extra']}
|
||||||
# don't check policy for admins using force
|
# don't check policy for admins using force
|
||||||
assert_policy('package_list', policy_data, force=force)
|
assert_policy('package_list', policy_data, force=force)
|
||||||
|
|
||||||
|
|
@ -1100,7 +1104,8 @@ def pkglist_unblock(taginfo, pkginfo, force=False):
|
||||||
tag = get_tag(taginfo, strict=True)
|
tag = get_tag(taginfo, strict=True)
|
||||||
pkg = lookup_package(pkginfo, strict=True)
|
pkg = lookup_package(pkginfo, strict=True)
|
||||||
context.session.assertLogin()
|
context.session.assertLogin()
|
||||||
policy_data = {'tag': tag['id'], 'action': 'unblock', 'package': pkg['id'], 'force': force}
|
policy_data = {'tag': tag['id'], 'action': 'unblock', 'package': pkg['id'],
|
||||||
|
'force' : force, 'extra': tag['extra']}
|
||||||
# don't check policy for admins using force
|
# don't check policy for admins using force
|
||||||
assert_policy('package_list', policy_data, force=force)
|
assert_policy('package_list', policy_data, force=force)
|
||||||
user = get_user(context.session.user_id)
|
user = get_user(context.session.user_id)
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,29 @@ def handle_list_sidetags(options, session, args):
|
||||||
|
|
||||||
for tag in session.listSideTags(basetag=opts.basetag, user=user):
|
for tag in session.listSideTags(basetag=opts.basetag, user=user):
|
||||||
print(tag["name"])
|
print(tag["name"])
|
||||||
|
|
||||||
|
|
||||||
|
@export_cli
|
||||||
|
def handle_edit_sidetag(options, session, args):
|
||||||
|
"Edit sidetag"
|
||||||
|
usage = _("usage: %(prog)s edit-sidetag [options]")
|
||||||
|
usage += _("\n(Specify the --help global option for a list of other help options)")
|
||||||
|
parser = ArgumentParser(usage=usage)
|
||||||
|
parser.add_argument("sidetag", help="name of sidetag")
|
||||||
|
parser.add_argument("--debuginfo", action="store_true", default=None,
|
||||||
|
help=_("Generate debuginfo repository"))
|
||||||
|
parser.add_argument("--no-debuginfo", action="store_false", dest="debuginfo")
|
||||||
|
parser.add_argument("-b", "--block", action="append", help="block package")
|
||||||
|
parser.add_argument("-u", "--unblock", action="append", help="unblock package")
|
||||||
|
|
||||||
|
opts = parser.parse_args(args)
|
||||||
|
|
||||||
|
activate_session(session, options)
|
||||||
|
|
||||||
|
kwargs = {
|
||||||
|
'block_pkgs': opts.block,
|
||||||
|
'unblock_pkgs': opts.unblock,
|
||||||
|
}
|
||||||
|
if opts.debuginfo is not None:
|
||||||
|
kwargs['debuginfo'] = opts.debuginfo
|
||||||
|
session.editSideTag(opts.sidetag, **kwargs)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ from kojihub import ( # noqa: F402
|
||||||
get_tag,
|
get_tag,
|
||||||
get_user,
|
get_user,
|
||||||
nextval
|
nextval
|
||||||
|
_edit_tag,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_FILE = "/etc/koji-hub/plugins/sidetag.conf"
|
CONFIG_FILE = "/etc/koji-hub/plugins/sidetag.conf"
|
||||||
|
|
@ -170,6 +171,49 @@ def listSideTags(basetag=None, user=None, queryOpts=None):
|
||||||
return query.execute()
|
return query.execute()
|
||||||
|
|
||||||
|
|
||||||
|
@export
|
||||||
|
def editSideTag(sidetag, debuginfo=None, block_pkgs=None, unblock_pkgs=None):
|
||||||
|
"""Restricted ability to modify sidetags, parent tag must have:
|
||||||
|
sidetag_debuginfo_allowed: 1
|
||||||
|
sidetag_package_list_allowed: 1
|
||||||
|
in extra, if modifying functions should work. For blocking/unblocking
|
||||||
|
further policy must be compatible with these operations.
|
||||||
|
|
||||||
|
:param sidetag: sidetag id or name
|
||||||
|
:type sidetag: int or str
|
||||||
|
:param debuginfo: set or disable debuginfo repo generation
|
||||||
|
:type debuginfo: bool
|
||||||
|
:param block_pkgs: package names to be blocked in sidetag
|
||||||
|
:type block_pkgs: list of str
|
||||||
|
:param unblock_pkgs: package names to be unblocked in sidetag
|
||||||
|
:type unblock_pkgs: list of str
|
||||||
|
"""
|
||||||
|
|
||||||
|
context.session.assertLogin()
|
||||||
|
user = get_user(context.session.user_id, strict=True)
|
||||||
|
tag = get_tag(sidetag, strict=True)
|
||||||
|
|
||||||
|
if not sidetag["extra"].get("sidetag"):
|
||||||
|
raise koji.GenericError("Not a sidetag: %(name)s" % sidetag)
|
||||||
|
if sidetag["extra"].get("sidetag_user_id") != user["id"]:
|
||||||
|
if not context.session.hasPerm("admin"):
|
||||||
|
raise koji.ActionNotAllowed("This is not your sidetag")
|
||||||
|
|
||||||
|
parent_id = getInheritanceData(sidetag)[0]['parent_id']
|
||||||
|
parent = get_tag(parent_id)
|
||||||
|
|
||||||
|
if debuginfo is not None and not parent['extra'].get('sidetag_debuginfo_allowed'):
|
||||||
|
raise koji.GenericError("Debuginfo setting is not allowed in parent tag.")
|
||||||
|
if (block_pkgs or unblock_pkgs) and not parent['extra'].get('sidetag_package_list_allowed'):
|
||||||
|
raise koji.GenericError("Package un/blocking is not allowed in parent tag.")
|
||||||
|
|
||||||
|
if debuginfo is not None:
|
||||||
|
_edit_tag(sidetag, extra={'with_debuginfo': bool(debuginfo)})
|
||||||
|
for pkg in block_pkgs:
|
||||||
|
pkglist_block(sidetag, pkg)
|
||||||
|
for pkg in unblock_pkgs:
|
||||||
|
pkglist_unblock(sidetag, pkg)
|
||||||
|
|
||||||
def handle_sidetag_untag(cbtype, *args, **kws):
|
def handle_sidetag_untag(cbtype, *args, **kws):
|
||||||
"""Remove a side tag when its last build is untagged
|
"""Remove a side tag when its last build is untagged
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
@mock.patch('kojihub.lookup_package')
|
@mock.patch('kojihub.lookup_package')
|
||||||
def test_pkglist_unblock(self, lookup_package, get_tag, assert_policy,
|
def test_pkglist_unblock(self, lookup_package, get_tag, assert_policy,
|
||||||
readPackageList, _pkglist_add, _pkglist_remove):
|
readPackageList, _pkglist_add, _pkglist_remove):
|
||||||
tag = {'id': 1, 'name': 'tag'}
|
tag = {'id': 1, 'name': 'tag', 'extra': {}}
|
||||||
pkg = {'id': 2, 'name': 'package', 'owner_id': 3}
|
pkg = {'id': 2, 'name': 'package', 'owner_id': 3}
|
||||||
get_tag.return_value = tag
|
get_tag.return_value = tag
|
||||||
lookup_package.return_value = pkg
|
lookup_package.return_value = pkg
|
||||||
|
|
@ -73,7 +73,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
get_tag.assert_called_once_with('tag', strict=True)
|
get_tag.assert_called_once_with('tag', strict=True)
|
||||||
lookup_package.assert_called_once_with('pkg', strict=True)
|
lookup_package.assert_called_once_with('pkg', strict=True)
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
||||||
'action': 'unblock', 'package': pkg['id'], 'force': False}, force=False)
|
'action': 'unblock', 'package': pkg['id'], 'force': False, 'extra': {}}, force=False)
|
||||||
self.assertEqual(readPackageList.call_count, 2)
|
self.assertEqual(readPackageList.call_count, 2)
|
||||||
readPackageList.assert_has_calls([
|
readPackageList.assert_has_calls([
|
||||||
mock.call(tag['id'], pkgID=pkg['id'], inherit=True),
|
mock.call(tag['id'], pkgID=pkg['id'], inherit=True),
|
||||||
|
|
@ -96,7 +96,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
def test_pkglist_unblock_inherited(self, lookup_package, get_tag, assert_policy,
|
def test_pkglist_unblock_inherited(self, lookup_package, get_tag, assert_policy,
|
||||||
readPackageList, _pkglist_add, _pkglist_remove):
|
readPackageList, _pkglist_add, _pkglist_remove):
|
||||||
tag_id, pkg_id, owner_id = 1, 2, 3
|
tag_id, pkg_id, owner_id = 1, 2, 3
|
||||||
get_tag.return_value = {'id': tag_id, 'name': 'tag'}
|
get_tag.return_value = {'id': tag_id, 'name': 'tag', 'extra': {}}
|
||||||
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
||||||
readPackageList.return_value = {pkg_id: {
|
readPackageList.return_value = {pkg_id: {
|
||||||
'blocked': True,
|
'blocked': True,
|
||||||
|
|
@ -109,7 +109,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
get_tag.assert_called_once_with('tag', strict=True)
|
get_tag.assert_called_once_with('tag', strict=True)
|
||||||
lookup_package.assert_called_once_with('pkg', strict=True)
|
lookup_package.assert_called_once_with('pkg', strict=True)
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
||||||
'action': 'unblock', 'package': pkg_id, 'force': False}, force=False)
|
'action': 'unblock', 'package': pkg_id, 'force': False, 'extra': {}}, force=False)
|
||||||
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
||||||
_pkglist_add.assert_called_once_with(tag_id, pkg_id, owner_id, False, '')
|
_pkglist_add.assert_called_once_with(tag_id, pkg_id, owner_id, False, '')
|
||||||
_pkglist_remove.assert_not_called()
|
_pkglist_remove.assert_not_called()
|
||||||
|
|
@ -123,7 +123,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
def test_pkglist_unblock_not_present(self, lookup_package, get_tag, assert_policy,
|
def test_pkglist_unblock_not_present(self, lookup_package, get_tag, assert_policy,
|
||||||
readPackageList, _pkglist_add, _pkglist_remove):
|
readPackageList, _pkglist_add, _pkglist_remove):
|
||||||
tag_id, pkg_id = 1, 2
|
tag_id, pkg_id = 1, 2
|
||||||
get_tag.return_value = {'id': tag_id, 'name': 'tag'}
|
get_tag.return_value = {'id': tag_id, 'name': 'tag', 'extra': {}}
|
||||||
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
||||||
readPackageList.return_value = {}
|
readPackageList.return_value = {}
|
||||||
|
|
||||||
|
|
@ -133,7 +133,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
get_tag.assert_called_once_with('tag', strict=True)
|
get_tag.assert_called_once_with('tag', strict=True)
|
||||||
lookup_package.assert_called_once_with('pkg', strict=True)
|
lookup_package.assert_called_once_with('pkg', strict=True)
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
||||||
'action': 'unblock', 'package': pkg_id, 'force': False}, force=False)
|
'action': 'unblock', 'package': pkg_id, 'force': False, 'extra': {}}, force=False)
|
||||||
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
||||||
_pkglist_add.assert_not_called()
|
_pkglist_add.assert_not_called()
|
||||||
_pkglist_remove.assert_not_called()
|
_pkglist_remove.assert_not_called()
|
||||||
|
|
@ -147,7 +147,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
def test_pkglist_unblock_not_blocked(self, lookup_package, get_tag, assert_policy,
|
def test_pkglist_unblock_not_blocked(self, lookup_package, get_tag, assert_policy,
|
||||||
readPackageList, _pkglist_add, _pkglist_remove):
|
readPackageList, _pkglist_add, _pkglist_remove):
|
||||||
tag_id, pkg_id, owner_id = 1, 2, 3
|
tag_id, pkg_id, owner_id = 1, 2, 3
|
||||||
get_tag.return_value = {'id': tag_id, 'name': 'tag'}
|
get_tag.return_value = {'id': tag_id, 'name': 'tag', 'extra': {}}
|
||||||
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
lookup_package.return_value = {'id': pkg_id, 'name': 'pkg'}
|
||||||
readPackageList.return_value = {pkg_id: {
|
readPackageList.return_value = {pkg_id: {
|
||||||
'blocked': False,
|
'blocked': False,
|
||||||
|
|
@ -162,7 +162,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
get_tag.assert_called_once_with('tag', strict=True)
|
get_tag.assert_called_once_with('tag', strict=True)
|
||||||
lookup_package.assert_called_once_with('pkg', strict=True)
|
lookup_package.assert_called_once_with('pkg', strict=True)
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
assert_policy.assert_called_once_with('package_list', {'tag': tag_id,
|
||||||
'action': 'unblock', 'package': pkg_id, 'force': False}, force=False)
|
'action': 'unblock', 'package': pkg_id, 'force': False, 'extra': {}}, force=False)
|
||||||
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
readPackageList.assert_called_once_with(tag_id, pkgID=pkg_id, inherit=True)
|
||||||
_pkglist_add.assert_not_called()
|
_pkglist_add.assert_not_called()
|
||||||
_pkglist_remove.assert_not_called()
|
_pkglist_remove.assert_not_called()
|
||||||
|
|
@ -200,7 +200,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
force=False
|
force=False
|
||||||
update=False
|
update=False
|
||||||
policy=True
|
policy=True
|
||||||
tag = {'id': 1, 'name': 'tag'}
|
tag = {'id': 1, 'name': 'tag', 'extra': {}}
|
||||||
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
||||||
users = [
|
users = [
|
||||||
{'id': 3, 'name': 'user'},
|
{'id': 3, 'name': 'user'},
|
||||||
|
|
@ -224,7 +224,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
mock.call(112233),
|
mock.call(112233),
|
||||||
])
|
])
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
||||||
'action': 'add', 'package': pkg['name'], 'force': False}, force=False)
|
'action': 'add', 'package': pkg['name'], 'force': False, 'extra': {}}, force=False)
|
||||||
self.assertEqual(self.run_callbacks.call_count, 2)
|
self.assertEqual(self.run_callbacks.call_count, 2)
|
||||||
self.run_callbacks.assert_has_calls([
|
self.run_callbacks.assert_has_calls([
|
||||||
mock.call('prePackageListChange', action='add', tag=tag,
|
mock.call('prePackageListChange', action='add', tag=tag,
|
||||||
|
|
@ -313,7 +313,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
force=False
|
force=False
|
||||||
update=False
|
update=False
|
||||||
policy=True
|
policy=True
|
||||||
tag = {'id': 1, 'name': 'tag'}
|
tag = {'id': 1, 'name': 'tag', 'extra': {}}
|
||||||
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
||||||
users = [
|
users = [
|
||||||
{'id': 3, 'name': 'user'},
|
{'id': 3, 'name': 'user'},
|
||||||
|
|
@ -341,7 +341,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
mock.call(112233),
|
mock.call(112233),
|
||||||
])
|
])
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
||||||
'action': 'add', 'package': pkg['name'], 'force': False}, force=False)
|
'action': 'add', 'package': pkg['name'], 'force': False, 'extra': {}}, force=False)
|
||||||
self.assertEqual(self.run_callbacks.call_count, 2)
|
self.assertEqual(self.run_callbacks.call_count, 2)
|
||||||
self.run_callbacks.assert_has_calls([
|
self.run_callbacks.assert_has_calls([
|
||||||
mock.call('prePackageListChange', action='add', tag=tag,
|
mock.call('prePackageListChange', action='add', tag=tag,
|
||||||
|
|
@ -370,7 +370,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
force=False
|
force=False
|
||||||
update=False
|
update=False
|
||||||
policy=True
|
policy=True
|
||||||
tag = {'id': 1, 'name': 'tag'}
|
tag = {'id': 1, 'name': 'tag', 'extra': {}}
|
||||||
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
||||||
users = [
|
users = [
|
||||||
{'id': 3, 'name': 'user',},
|
{'id': 3, 'name': 'user',},
|
||||||
|
|
@ -398,7 +398,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
mock.call(112233),
|
mock.call(112233),
|
||||||
])
|
])
|
||||||
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
assert_policy.assert_called_once_with('package_list', {'tag': tag['id'],
|
||||||
'action': 'add', 'package': pkg['name'], 'force': False}, force=False)
|
'action': 'add', 'package': pkg['name'], 'force': False, 'extra': {}}, force=False)
|
||||||
self.run_callbacks.assert_called_once_with(
|
self.run_callbacks.assert_called_once_with(
|
||||||
'prePackageListChange', action='add', tag=tag,
|
'prePackageListChange', action='add', tag=tag,
|
||||||
package=pkg, owner=user['id'], block=block,
|
package=pkg, owner=user['id'], block=block,
|
||||||
|
|
@ -420,7 +420,7 @@ class TestPkglistBlock(unittest.TestCase):
|
||||||
force=True
|
force=True
|
||||||
update=False
|
update=False
|
||||||
policy=True
|
policy=True
|
||||||
tag = {'id': 1, 'name': 'tag'}
|
tag = {'id': 1, 'name': 'tag', 'extra': {}}
|
||||||
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
pkg = {'id': 2, 'name': 'pkg', 'owner_id': 3}
|
||||||
users = [
|
users = [
|
||||||
{'id': 3, 'name': 'user',},
|
{'id': 3, 'name': 'user',},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue