def view_permissions(user_id: int = None, all: bool = False) -> flask.Response: """ View all permissions available. Requires the ``permissions_modify`` permission. .. :quickref: Permission; View available permissions. **Example response**: .. parsed-literal:: { "status": "success", "response": [ "list_permissions", "permissions_modify", "users_change_password" ] } :>json list response: A list of permission name strings :statuscode 200: View successful :statuscode 403: User lacks sufficient permissions to view permissions """ return flask.jsonify({'permissions': Permissions.get_all_permissions()})
def PermissionsList(perm_list: List[str]) -> List[str]: """ Validates that every permission in the list is a valid permission. :param perm_list: A list of permissions encoded as ``str`` :return: The inputted perm_list :raises Invalid: If a permission in the list isn't valid or input isn't a list """ invalid = [] if isinstance(perm_list, list): for perm in perm_list: if not Permissions.is_valid_permission(perm): invalid.append(perm) else: raise Invalid('Permissions must be in a list,') if invalid: raise Invalid( f'The following permissions are invalid: {", ".join(invalid)},') return perm_list
def __call__(self, permissions: dict) -> dict: """ :param permissions: Dictionary of permissions and booleans :return: The input value :raises Invalid: A permission name is invalid or a value isn't a bool """ permissioned = self.restrict is None or flask.g.user.has_permission( self.restrict) if isinstance(permissions, dict): for perm_name, action in permissions.items(): if not isinstance(action, bool): raise Invalid('permission actions must be booleans') elif not Permissions.is_valid_permission( perm_name, permissioned) and not (permissioned and action is False): # Do not disallow removal of non-existent permissions. raise Invalid(f'{perm_name} is not a valid permission') else: raise Invalid('input value must be a dictionary') return permissions
def change_user_permissions(user: User, permissions: Dict[str, bool]) -> None: """ Change the permissions belonging to a user. Permissions can be added to a user, deleted from a user, and ungranted from a user. Adding a permission occurs when the user does not have the specified permission, through custom or userclass. There are two types of permission removal: deletion and ungranting. Deletion ocrurs when the user has the permission through custom, while ungranting occurs when the user has the permission through userclass. If they have both custom and userclass, they will lose both. :param user: The user to change permissions for :param permissions: The permissions to change :raises APIException: Invalid permissions to change """ to_add, to_ungrant, to_delete = check_permissions(user, permissions) for p in to_ungrant: if not Permissions.is_valid_permission(p): raise APIException(f'{p} is not a valid permission.') alter_permissions(user, to_add, to_ungrant, to_delete) cache.delete(user.__cache_key_permissions__.format(id=user.id)) user.del_property_cache('permissions')
def __init__(self, secret_passphrase): # setup log and config # needs a false setting on first in case config does not # load (like after changes). self.storage = False self.log = logging.getLogger('Wrapper.py') self.configManager = Config() self.configManager.loadconfig() self.config = self.configManager.config # Read Config items # hard coded cursor for non-readline mode self.cursor = ">" # This was to allow alternate encodings self.encoding = self.config["General"]["encoding"] self.serverpath = self.config["General"]["server-directory"] self.proxymode = self.config["Proxy"]["proxy-enabled"] self.wrapper_onlinemode = self.config["Proxy"]["online-mode"] self.halt_message = self.config["Misc"]["halt-message"] # encryption items (for passwords and sensitive user data) # salt is generated and stored in wrapper.properties.json config_changes = False salt = self.config["General"]["salt"] if not salt: salt = gensalt(self.encoding) self.config["General"]["salt"] = salt config_changes = True # passphrase is provided at startup by the wrapper operator or script (not stored) passphrase = phrase_to_url_safebytes(secret_passphrase, self.encoding, salt) self.cipher = Crypt(passphrase, self.encoding) # Update passwords (hash any plaintext passwords) for groups in self.config: for cfg_items in self.config[groups]: if cfg_items[-10:] == "-plaintext": # i.e., cfg_items ===> like ["web-password-plaintext"] hash_item = cfg_items[:-10] # hash_item ===> i.e., ["web-password"] if hash_item in self.config[groups] and self.config[ groups][cfg_items]: # encrypt contents of (i.e.) ["web-password-plaintext"] hashed_item = self.cipher.encrypt( self.config[groups][cfg_items]) # store in "" ["Web"]["web-password"] self.config[groups][hash_item] = hashed_item # set plaintext item to false (successful digest) self.config[groups][cfg_items] = False config_changes = True # Patch any old update paths "..wrapper/development/build/version.json" # new paths are: "..wrapper/development" for entries in self.config["Updates"]: if "/build/version.json" in str(self.config["Updates"][entries]): oldentry = copy.copy(self.config["Updates"][entries]) self.config["Updates"][entries] = oldentry.split( "/build/version.json")[0] config_changes = True # save changes made to config file if config_changes: self.configManager.save() # reload branch update info. self.auto_update_wrapper = self.config["Updates"][ "auto-update-wrapper"] self.auto_update_branch = self.config["Updates"]["auto-update-branch"] if not self.auto_update_branch: self.update_url = "https://raw.githubusercontent.com/benbaptist/minecraft-wrapper/development" else: self.update_url = self.config["Updates"][self.auto_update_branch] self.use_timer_tick_event = self.config["Gameplay"][ "use-timer-tick-event"] self.use_readline = not (self.config["Misc"]["use-betterconsole"]) # Storages self.wrapper_storage = Storage("wrapper", encoding=self.encoding) self.wrapper_permissions = Storage("permissions", encoding=self.encoding, pickle=False) self.wrapper_usercache = Storage("usercache", encoding=self.encoding, pickle=False) # storage Data objects self.storage = self.wrapper_storage.Data self.usercache = self.wrapper_usercache.Data # self.wrapper_permissions accessed only by permissions module # core functions and datasets self.perms = Permissions(self) self.uuids = UUIDS(self.log, self.usercache) self.plugins = Plugins(self) self.commands = Commands(self) self.events = Events(self) self.players = {} self.registered_permissions = {} self.help = {} self.input_buff = "" self.sig_int = False self.command_hist = ['/help', 'help'] self.command_index = 1 # init items that are set up later (or opted out of/ not set up.) self.javaserver = None self.api = None self.irc = None self.scripts = None self.web = None self.proxy = None self.backups = None # HaltSig - Why? ... because if self.halt was just `False`, passing # a self.halt would simply be passing `False` (immutable). Changing # the value of self.halt would not necessarily change the value of the # passed parameter (unless it was specifically referenced back as # `wrapper.halt`). Since the halt signal needs to be passed, possibly # several layers deep, and into modules that it may be desireable to # not have direct access to wrapper, using a HaltSig object is # more desireable and reliable in behavior. self.halt = HaltSig() self.updated = False # future plan to expose this to api self.xplayer = ConsolePlayer(self) # Error messages for non-standard import failures. if not readline and self.use_readline: self.log.warning( "'readline' not imported. This is needed for proper" " console functioning. Press <Enter> to acknowledge...") sys.stdin.readline() # requests is just being used in too many places to try # and track its usages piece-meal. if not requests: self.log.error( "You must have the requests module installed to use wrapper!" " console functioning. Press <Enter> to Exit...") sys.stdin.readline() self._halt() # create server/proxy vitals and config objects self.servervitals = ServerVitals(self.players) # LETS TAKE A SECOND TO DISCUSS PLAYER OBJECTS: # The ServerVitals class gets passed the player object list now, but # player objects are now housed in wrapper. This is how we are # passing information between proxy and wrapper. self.servervitals.serverpath = self.config["General"][ "server-directory"] self.servervitals.state = OFF self.servervitals.command_prefix = self.config["Misc"][ "command-prefix"] self.proxyconfig = ProxyConfig() self.proxyconfig.proxy = self.config["Proxy"] self.proxyconfig.entity = self.config["Entities"]
def listperms(): """List all active permissions.""" for p in list(sorted(Permissions.get_all_permissions())): click.echo(p)
def __init__(self): # setup log and config # needs a false setting on first in case config does not # load (like after changes). self.storage = False self.log = logging.getLogger('Wrapper.py') self.configManager = Config() self.configManager.loadconfig() # set up config self.config = self.configManager.config # Read Config items # hard coded cursor for non-readline mode self.cursor = ">" self.wrapper_ban_system = False # This was to allow alternate encodings self.encoding = self.config["General"]["encoding"] self.proxymode = self.config["Proxy"]["proxy-enabled"] self.wrapper_onlinemode = self.config["Proxy"]["online-mode"] self.wrapper_ban_system = self.proxymode and self.wrapper_ban_system self.auto_update_wrapper = self.config["Updates"][ "auto-update-wrapper"] self.auto_update_branch = self.config["Updates"]["auto-update-branch"] self.use_timer_tick_event = self.config["Gameplay"][ "use-timer-tick-event"] self.command_prefix = self.config["Misc"]["command-prefix"] self.use_readline = self.config["Misc"]["use-readline"] # Storages self.wrapper_storage = Storage("wrapper", encoding=self.encoding) self.wrapper_permissions = Storage("permissions", encoding=self.encoding, pickle=False) self.wrapper_usercache = Storage("usercache", encoding=self.encoding, pickle=False) # storage Data objects self.storage = self.wrapper_storage.Data self.permissions = self.wrapper_permissions.Data self.usercache = self.wrapper_usercache.Data # core functions and datasets self.perms = Permissions(self) self.uuids = UUIDS(self) self.plugins = Plugins(self) self.commands = Commands(self) self.events = Events(self) self.registered_permissions = {} self.help = {} self.input_buff = "" self.sig_int = False self.command_hist = ['/help', 'help'] self.command_index = 1 # init items that are set up later (or opted out of/ not set up.) self.javaserver = None self.api = None self.irc = None self.scripts = None self.web = None self.proxy = None self.backups = None self.halt = False self.updated = False # future plan to expose this to api self.xplayer = ConsolePlayer(self) # define the slot once here and not at each clients Instantiation: self.inv_slots = range(46) # Error messages for non-standard import failures. if not readline and self.use_readline: self.log.warning( "'readline' not imported. This is needed for proper" " console functioning. Press <Enter> to acknowledge...") sys.stdin.readline() # requests is just being used in too many places to try # and track its usages piece-meal. if not requests: self.log.error( "You must have the requests module installed to use wrapper!" " console functioning. Press <Enter> to Exit...") sys.stdin.readline() self._halt()
def __init__(self, subject: Urn, object: Urn, value: Permissions): self.subject = subject self.object = object self.value = value if isinstance(value, Permissions) \ else Permissions(value)