From ebb44773c20863b0fcd0bc0bc8714c1217446025 Mon Sep 17 00:00:00 2001 From: Adarnof Date: Mon, 12 Jun 2017 22:14:35 -0400 Subject: [PATCH] New view_state_corpstats permission Cleanup CorpStats permissions --- corputils/auth_hooks.py | 13 +++--- corputils/managers.py | 3 ++ .../migrations/0002_migrate_permissions.py | 11 +++-- ...tringy.py => 0003_granular_permissions.py} | 0 corputils/migrations/0004_member_models.py | 2 +- .../migrations/0005_cleanup_permissions.py | 40 +++++++++++++++++++ corputils/models.py | 5 +-- corputils/views.py | 2 +- docs/features/corpstats.md | 13 ++---- 9 files changed, 61 insertions(+), 28 deletions(-) rename corputils/migrations/{0003_make_strings_more_stringy.py => 0003_granular_permissions.py} (100%) create mode 100644 corputils/migrations/0005_cleanup_permissions.py diff --git a/corputils/auth_hooks.py b/corputils/auth_hooks.py index 59613ae1..14367ebe 100644 --- a/corputils/auth_hooks.py +++ b/corputils/auth_hooks.py @@ -12,8 +12,10 @@ class CorpStats(MenuItemHook): navactive=['corputils:']) def render(self, request): - if request.user.has_perm('corputils.view_corp_corpstats') or request.user.has_perm('corputils.view_alliance_corpstats') or request.user.has_perm('corputils.add_corpstats'): - return MenuItemHook.render(self, request) + if request.user.has_perm('corputils.view_corp_corpstats') or request.user.has_perm( + 'corputils.view_alliance_corpstats') or request.user.has_perm( + 'corputils.add_corpstats') or request.user.has_perm('corputils.view_state_corpstats'): + return MenuItemHook.render(self, request) return '' @@ -22,11 +24,6 @@ def register_menu(): return CorpStats() -class CorpStatsUrl(UrlHook): - def __init__(self): - UrlHook.__init__(self, urls, 'corputils', r'^corpstats/') - - @hooks.register('url_hook') def register_url(): - return CorpStatsUrl() + return UrlHook(urls, 'corputils', r'^corpstats/') diff --git a/corputils/managers.py b/corputils/managers.py index 94539083..6186381c 100644 --- a/corputils/managers.py +++ b/corputils/managers.py @@ -16,6 +16,9 @@ class CorpStatsQuerySet(models.QuerySet): queries.append(models.Q(corp__corporation_id=char.corporation_id)) if user.has_perm('corputils.view_alliance_corpstats'): queries.append(models.Q(corp__alliance__alliance_id=char.alliance_id)) + if user.has_perm('corputils.view_state_corpstats'): + queries.append(models.Q(corp__in=user.profile.state.member_corporations.all())) + queries.append(models.Q(corp__alliance__in=user.profile.state.member_alliances.all())) # filter based on queries query = queries.pop() diff --git a/corputils/migrations/0002_migrate_permissions.py b/corputils/migrations/0002_migrate_permissions.py index ba2c74bd..4650bbc9 100644 --- a/corputils/migrations/0002_migrate_permissions.py +++ b/corputils/migrations/0002_migrate_permissions.py @@ -19,6 +19,7 @@ PERMISSIONS = { } } + def user_permissions_dict(apps): Permission = apps.get_model('auth', 'Permission') ContentType = apps.get_model('contenttypes', 'ContentType') @@ -33,14 +34,17 @@ def user_permissions_dict(apps): 'corpstats': {x: Permission.objects.get_or_create(codename=x, name=y, content_type=corpstats_ct)[0] for x, y in PERMISSIONS['corpstats'].items()}, } + def users_with_permission(apps, perm): User = apps.get_model('auth', 'User') return User.objects.filter(user_permissions=perm.pk) + def groups_with_permission(apps, perm): Group = apps.get_model('auth', 'Group') return Group.objects.filter(permissions=perm.pk) + def forward(apps, schema_editor): perm_dict = user_permissions_dict(apps) @@ -66,8 +70,9 @@ def forward(apps, schema_editor): for name, perm in perm_dict['user'].items(): perm.delete() - -def reverse(apps, schema_editor): + + +def reverse(apps, schema_editor): perm_dict = user_permissions_dict(apps) corp_users = users_with_permission(apps, perm_dict['corpstats']['view_corp_corpstats']) @@ -79,7 +84,6 @@ def reverse(apps, schema_editor): u.user_permissions.remove(perm_dict['corpstats']['view_corp_corpstats'].pk) for u in corp_api_users: u.user_permissions.remove(perm_dict['corpstats']['corp_apis'].pk) - alliance_users = users_with_permission(apps, perm_dict['corpstats']['view_alliance_corpstats']) alliance_api_users = users_with_permission(apps, perm_dict['corpstats']['alliance_apis']) @@ -93,7 +97,6 @@ def reverse(apps, schema_editor): corp_groups = groups_with_permission(apps, perm_dict['corpstats']['view_corp_corpstats']) corp_api_groups = groups_with_permission(apps, perm_dict['corpstats']['corp_apis']) - corp_gs = corp_groups | corp_api_groups for g in corp_groups.distinct(): g.permissions.add(perm_dict['user']['corp_apis'].pk) for g in corp_groups: diff --git a/corputils/migrations/0003_make_strings_more_stringy.py b/corputils/migrations/0003_granular_permissions.py similarity index 100% rename from corputils/migrations/0003_make_strings_more_stringy.py rename to corputils/migrations/0003_granular_permissions.py diff --git a/corputils/migrations/0004_member_models.py b/corputils/migrations/0004_member_models.py index 6a3516cb..d73c4f61 100644 --- a/corputils/migrations/0004_member_models.py +++ b/corputils/migrations/0004_member_models.py @@ -27,7 +27,7 @@ def convert_members_to_json(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('corputils', '0003_make_strings_more_stringy'), + ('corputils', '0003_granular_permissions'), ] operations = [ diff --git a/corputils/migrations/0005_cleanup_permissions.py b/corputils/migrations/0005_cleanup_permissions.py new file mode 100644 index 00000000..21676e9e --- /dev/null +++ b/corputils/migrations/0005_cleanup_permissions.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.2 on 2017-06-10 15:34 +from __future__ import unicode_literals + +from django.db import migrations + + +def delete_permissions(apps, schema_editor): + CorpStats = apps.get_model('corputils', 'CorpStats') + ContentType = apps.get_model('contenttypes', 'ContentType') + Permission = apps.get_model('auth', 'Permission') + ct = ContentType.objects.get_for_model(CorpStats) + perms = Permission.objects.filter(content_type=ct) + perms.filter(codename__contains='api').delete() + perms.filter(codename='view_corpstats').delete() + perms.filter(codename__contains='blue').delete() + perms.filter(codename__contains='remove').delete() + + g = perms.get(codename='view_corp_corpstats') + g.name = 'Can view corp stats of their corporation.' + g.save() + + g = perms.get(codename='view_alliance_corpstats') + g.name = 'Can view corp stats of members of their alliance.' + g.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('corputils', '0004_member_models'), + ] + + operations = [ + migrations.AlterModelOptions( + name='corpstats', + options={'permissions': (('view_corp_corpstats', 'Can view corp stats of their corporation.'), ('view_alliance_corpstats', 'Can view corp stats of members of their alliance.'), ('view_state_corpstats', 'Can view corp stats of members of their auth state.')), 'verbose_name': 'corp stats', 'verbose_name_plural': 'corp stats'}, + ), + migrations.RunPython(delete_permissions, migrations.RunPython.noop), + ] diff --git a/corputils/models.py b/corputils/models.py index cbf62f22..3ae3fe84 100644 --- a/corputils/models.py +++ b/corputils/models.py @@ -21,12 +21,9 @@ class CorpStats(models.Model): class Meta: permissions = ( - ('corp_apis', 'Can view API keys of members of their corporation.'), - ('alliance_apis', 'Can view API keys of members of their alliance.'), - ('blue_apis', 'Can view API keys of members of blue corporations.'), ('view_corp_corpstats', 'Can view corp stats of their corporation.'), ('view_alliance_corpstats', 'Can view corp stats of members of their alliance.'), - ('view_blue_corpstats', 'Can view corp stats of blue corporations.'), + ('view_state_corpstats', 'Can view corp stats of members of their auth state.'), ) verbose_name = "corp stats" verbose_name_plural = "corp stats" diff --git a/corputils/views.py b/corputils/views.py index 62d1b54c..3e12afb4 100644 --- a/corputils/views.py +++ b/corputils/views.py @@ -14,7 +14,7 @@ from bravado.exception import HTTPError def access_corpstats_test(user): return user.has_perm('corputils.view_corp_corpstats') or user.has_perm( - 'corputils.view_alliance_corpstats') or user.has_perm('corputils.view_blue_corpstats') + 'corputils.view_alliance_corpstats') or user.has_perm('corputils.view_state_corpstats') @login_required diff --git a/docs/features/corpstats.md b/docs/features/corpstats.md index 914a0fc1..05ce1bf4 100644 --- a/docs/features/corpstats.md +++ b/docs/features/corpstats.md @@ -89,17 +89,11 @@ To use this feature, users will require some of the following: +---------------------------------------+------------------+----------------------------------------------------+ | Permission | Admin Site | Auth Site | +=======================================+==================+====================================================+ -| corpstats.corp_apis | None | Can view API keys of members of their corporation. | -+---------------------------------------+------------------+----------------------------------------------------+ -| corpstats.alliance_apis | None | Can view API keys of members of their alliance. | -+---------------------------------------+------------------+----------------------------------------------------+ -| corpstats.blue_apis | None | Can view API keys of members of blue corporations. | -+---------------------------------------+------------------+----------------------------------------------------+ | corpstats.view_corp_corpstats | None | Can view corp stats of their corporation. | +---------------------------------------+------------------+----------------------------------------------------+ | corpstats.view_alliance_corpstats | None | Can view corp stats of members of their alliance. | +---------------------------------------+------------------+----------------------------------------------------+ -| corpstats.view_blue_corpstats | None | Can view corp stats of blue corporations. | +| corpstats.view_state_corpstats | None | Can view corp stats of members of their auth state.| +---------------------------------------+------------------+----------------------------------------------------+ | corpstats.add_corpstats | Can create model | Can add new corpstats using an SSO token. | +---------------------------------------+------------------+----------------------------------------------------+ @@ -110,8 +104,7 @@ To use this feature, users will require some of the following: ``` -Typical use-cases would see the bundling of `corp_apis` and `view_corp_corpstats`, same for alliances and blues. -Alliance permissions supersede corp permissions. Note that these evaluate against the user's main character. +Users who add a Corp Stats with their token will be granted permissions to view it regardless of the above permissions. View permissions are interpreted in the "OR" sense: a user can view their corp's Corp Stats without the `view_corp_corpstats` permission if they have the `view_alliance_corpstats` permission, same idea for their state. Note that these evaluate against the user's main character. ## Troubleshooting @@ -138,7 +131,7 @@ Any of the following errors will result in a notification to the owning user, an This occurs when the SSO token is invalid, which can occur when deleted by the user, the character is transferred between accounts, or the API is having a bad day. ->CorpStats for corp_name cannot update with your ESI token as you have left corp. +>CorpStats for (corp name) cannot update with your ESI token as you have left corp. The SSO token's character is no longer in the corp which the Corp Stats is for, and therefore membership data cannot be retrieved.