diff --git a/GeoffreyApp/api/commands.py b/GeoffreyApp/api/commands.py index ad3155b..cb581ed 100644 --- a/GeoffreyApp/api/commands.py +++ b/GeoffreyApp/api/commands.py @@ -15,12 +15,6 @@ class RequestTypes(enum.Enum): GET = "GET" -class PermissionLevel(enum.Enum): - ADMIN = enum.auto() - MOD = enum.auto() - PLAYER = enum.auto() - - command_dict = {RequestTypes.GET: {}, RequestTypes.POST: {}} @@ -56,11 +50,11 @@ class Command: return {"command": self.name, "help": self.help, "permission_level": self.permission_level.name} -def command(type, permission_level=PermissionLevel.PLAYER): +def command(type, permission_level=PermissionLevel.PLAYER, command_name=None): def command_dec(func): def add_command(): - command = Command(func, permission_level) - command_dict[type][command.name] = command + command_obj = Command(func, permission_level, command_name=command_name) + command_dict[type][command_obj.name] = command_obj return func return add_command() @@ -76,6 +70,14 @@ def match_tunnel(tunnel_direction): raise InvalidTunnelError +def get_player_by_name(mc_username): + try: + uuid = grab_UUID(mc_username) + return get_player(mc_uuid=uuid) + except UsernameLookupFailed: + raise PlayerNotFound + + def get_player(discord_uuid=None, mc_uuid=None): try: discord_uuid = str(discord_uuid) @@ -806,3 +808,36 @@ def remove_resident(resident_name, town_name, discord_uuid=None, mc_uuid=None): town.save() return town.json + + +@command(RequestTypes.POST, permission_level=PermissionLevel.MOD) +def mod_delete(player_name, location_name): + uuid = grab_UUID(player_name) + delete(location_name, mc_uuid=uuid) + + +@command(RequestTypes.POST, permission_level=PermissionLevel.MOD) +def mod_delete_item(player_name, item_name, shop_name): + uuid = grab_UUID(player_name) + delete_item(item_name, shop_name=shop_name, mc_uuid=uuid) + + +@command(RequestTypes.POST, permission_level=PermissionLevel.MOD) +def mod_edit_name(player_name, new_name, loc_name): + uuid = grab_UUID(player_name) + edit_name(new_name, loc_name, mc_uuid=uuid) + + +@command(RequestTypes.POST, permission_level=PermissionLevel.MOD) +def mod_remove_resident(player_name, resident_name, town_name): + uuid = grab_UUID(player_name) + remove_resident(resident_name, town_name, mc_uuid=uuid) + + +@command(RequestTypes.POST, permission_level=PermissionLevel.MOD) +def mod_remove_owner(player_name, loc_name): + uuid = grab_UUID(player_name) + owner = get_player(mc_uuid=uuid) + + location = get_location(owner, loc_name) + location.owner.remove(owner) diff --git a/GeoffreyApp/api/views.py b/GeoffreyApp/api/views.py index cbdbd88..b231c65 100644 --- a/GeoffreyApp/api/views.py +++ b/GeoffreyApp/api/views.py @@ -7,20 +7,26 @@ import sys from GeoffreyApp.api.commands import RequestTypes import GeoffreyApp.api.commands as commands from GeoffreyApp.errors import * -from GeoffreyApp.models import APIToken +from GeoffreyApp.models import APIToken, PermissionLevel -def check_token(request, **kwargs): +def check_key(key, **kwargs): + if APIToken.objects.filter(key=key, **kwargs).exists(): + return True + else: + return False + + +def check_request_for_key(request): if "api" in request: key = request["api"] - if APIToken.objects.filter(key=key, **kwargs).exists(): - return True + return APIToken.objects.get(key=key) - return False + return None -def run_command(request, command_name, req_type): +def run_command(request, command_name, req_type, key): params = request.dict() params.pop("api") @@ -28,7 +34,11 @@ def run_command(request, command_name, req_type): try: if command_name in commands.command_dict[req_type]: command = commands.command_dict[req_type][command_name] - response = command.func(**params) + + if key.has_command_permission(command.permission_level): + response = command.func(**params) + else: + response = {} else: raise CommandNotFound except Exception as e: @@ -39,14 +49,16 @@ def run_command(request, command_name, req_type): return JsonResponse(response, safe=False) -def get_commands(): +def get_commands(key): command_list = [] for request in commands.command_dict: for command_name in commands.command_dict[request]: command = commands.command_dict[request][command_name] json = command.json - command_list.append(json) + + if key.has_command_permission(command.permission_level): + command_list.append(json) return command_list @@ -54,25 +66,28 @@ def get_commands(): class CommandAPI(View): def get(self, request, command): get = request.GET - if check_token(get, commands_perm=True): + key = check_request_for_key(get) + if key is not None: if command.lower() == "commands": - return JsonResponse(get_commands(), safe=False) + return JsonResponse(get_commands(key), safe=False) else: - return run_command(get, command, RequestTypes.GET) - else: - return JsonResponse({}) + return run_command(get, command, RequestTypes.GET, key) + return JsonResponse({}) def post(self, request, command): post = request.POST - if check_token(post, commands_perm=True): - return run_command(post, command, RequestTypes.POST) + key = check_request_for_key(request) + + if key is not None: + return run_command(post, command, RequestTypes.POST, key) else: return JsonResponse({}) class SettingsAPI(View): def get(self, request): - if check_token(request.GET, commands_perm=True): + key = check_request_for_key(request.GET) + if key.has_command_permission(PermissionLevel.PLAYER): response = { "BOT_PREFIX": getattr(settings, 'GEOFFREY_BOT_PREFIX', '?'), "ERROR_USERS": getattr(settings, 'GEOFFREY_BOT_ERROR_USERS', []), diff --git a/GeoffreyApp/models.py b/GeoffreyApp/models.py index a51581e..facecd9 100644 --- a/GeoffreyApp/models.py +++ b/GeoffreyApp/models.py @@ -3,12 +3,18 @@ from django.conf import settings from django.urls import reverse from sys import maxsize import datetime +import enum from GeoffreyApp.util import create_token, objects_list_to_json # Create your models here. +class PermissionLevel(enum.Enum): + ADMIN = enum.auto() + MOD = enum.auto() + PLAYER = enum.auto() + class APIToken(models.Model): key = models.CharField(default=create_token, max_length=25, unique=True) @@ -26,6 +32,25 @@ class APIToken(models.Model): Permission to use the command api """ + mod_commands_perm = models.BooleanField(default=False) + """ + Permission to use mod commands + """ + admin_commands_perm = models.BooleanField(default=False) + """ + Permission to use admin commands + """ + + def has_command_permission(self, permission_level): + if permission_level == PermissionLevel.ADMIN: + return self.admin_commands_perm + elif permission_level == PermissionLevel.MOD: + return self.admin_commands_perm + elif permission_level == PermissionLevel.PLAYER: + return self.commands_perm + else: + return False + def __str__(self): if len(self.name): return "{}: {}".format(self.name, self.key) @@ -263,7 +288,6 @@ class Base(Location): info_page = "GeoffreyBaseInfo" - class Town(Location): info_page = "GeoffreyTownInfo"