Skip to content

Commit d4ea13a

Browse files
committed
Initial commit of the new auth API
TODO: Fill in commands and add translations for all phrases
1 parent d755256 commit d4ea13a

File tree

14 files changed

+306
-522
lines changed

14 files changed

+306
-522
lines changed

addons/source-python/packages/source-python/__init__.py

+2-10
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,9 @@ def setup_sp_command():
127127
# =============================================================================
128128
def setup_auth():
129129
"""Set up authentification."""
130-
from core.command import _core_command
131-
from core.settings import _core_settings
132-
133-
# Get the auth providers that should be loaded
134-
auth_providers = _core_settings['AUTH_SETTINGS']['providers'].split()
135-
136-
# Should any providers be loaded?
137-
if auth_providers:
130+
from auth.manager import auth_manager
138131

139-
# Load the auth providers
140-
_core_command['auth'].call_command(['load'] + auth_providers)
132+
auth_manager.load()
141133

142134

143135
# =============================================================================

addons/source-python/packages/source-python/auth/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
# Translations
1212
from translations.strings import LangStrings
1313

14+
from . import commands
15+
1416

1517
# =============================================================================
1618
# >> GLOBAL VARIABLES
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import os
2+
import json
3+
4+
from auth.paths import AUTH_CFG_PATH
5+
from auth.base import PermissionSource
6+
from auth.manager import auth_manager
7+
8+
9+
class FlatfilePermissionSource(PermissionSource):
10+
name = "flatfile"
11+
options = {
12+
"admin_config_path": AUTH_CFG_PATH.joinpath("admins.json"),
13+
"group_config_path": AUTH_CFG_PATH.joinpath("groups.json"),
14+
"simple_config_path": AUTH_CFG_PATH.joinpath("simple.txt")
15+
}
16+
17+
def load(self):
18+
self.load_config(auth_manager.players, self.options["admin_config_path"])
19+
self.load_config(auth_manager.groups, self.options["group_config_path"])
20+
self.load_simple_config(auth_manager.players, self.options["simple_config_path"])
21+
22+
@staticmethod
23+
def load_config(store, path):
24+
if not os.path.exists(path):
25+
with open(path, "w") as file:
26+
json.dump({}, file)
27+
with open(path) as file:
28+
try:
29+
nodes = json.load(file)
30+
for nodename, node in nodes.items():
31+
nodename = nodename.strip()
32+
for permission in node.get("permissions", set()):
33+
if permission != "":
34+
store[nodename].add(permission)
35+
for group in node.get("parents", set()):
36+
store[nodename].add_parent(group)
37+
except ValueError:
38+
print("Malformed permissions file: {}".format(path))
39+
40+
@staticmethod
41+
def load_simple_config(store, path):
42+
if not os.path.exists(path):
43+
open(path, "w").close()
44+
with open(path) as file:
45+
for uniqueid in file.readlines():
46+
store[uniqueid.strip()].add("*")
47+
48+
source = FlatfilePermissionSource()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class PermissionSource(object):
2+
name = ""
3+
options = {}
4+
5+
def load(self):
6+
pass
7+
8+
def unload(self):
9+
pass
10+
11+
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,80 @@
1-
# ../auth/commands.py
1+
# TODO Add commands to add/remove permissions once command filters are added
22

3-
"""Registers the "sp auth" sub-commands."""
3+
from players.entity import PlayerEntity
44

5-
# =============================================================================
6-
# >> IMPORTS
7-
# =============================================================================
8-
# Python Imports
9-
# Collections
10-
from collections import OrderedDict
5+
from commands.client import ClientCommand
6+
from commands.server import ServerCommand
7+
from .manager import auth_manager
118

12-
# Source.Python imports
13-
# Auth
14-
from auth import auth_logger
15-
from auth import _auth_strings
16-
from auth.manager import auth_manager
9+
from messages import SayText2
1710

11+
import re
1812

19-
# =============================================================================
20-
# >> GLOBAL VARIABLES
21-
# =============================================================================
22-
# Get the sp.auth.commands logger
23-
auth_commands_logger = auth_logger.commands
2413

14+
argument_re = re.compile("<([^>]+)>")
2515

26-
# =============================================================================
27-
# >> CLASSES
28-
# =============================================================================
29-
class _AuthCommands(OrderedDict):
30-
"""Class used for executing "sp auth" sub-command functionality."""
3116

32-
manager = auth_manager
17+
class AuthCommand(object):
18+
def __init__(self, command, permission=None):
19+
self.permission = permission
20+
self.command = command
21+
self.arguments = []
22+
for arg in command.split(" "):
23+
if argument_re.match(arg):
24+
self.arguments.append(None)
25+
else:
26+
self.arguments.append(arg)
27+
self.callback = None
3328

34-
def call_command(self, args):
35-
"""Execute the given "sp auth" sub-command."""
36-
# Was a command given?
37-
if not args:
29+
def __call__(self, callback, *args, **kwargs):
30+
self.callback = callback
31+
return callback
3832

39-
# Get a message that a sub-command is needed
40-
message = '[SP Auth] ' + _auth_strings[
41-
'Missing Command'].get_string() + '\n'
42-
43-
# Print the auth help text
44-
self.print_auth_help(message)
45-
46-
# No need to go further
33+
def test(self, index, command):
34+
if command.get_arg_count() - 1 != len(self.arguments):
4735
return
48-
49-
# Get the command
50-
command = args[0]
51-
52-
# Is the command registered?
53-
if command not in self:
54-
55-
# Get a message about the invalid command
56-
message = '[SP Auth] ' + _auth_strings[
57-
'Invalid Sub-Command'].get_string(command=command) + '\n'
58-
59-
# Print the auth help text
60-
self.print_auth_help(message)
61-
62-
# No need to go further
63-
return
64-
65-
# Does the given command use arguments?
66-
if hasattr(self[command], 'args'):
67-
68-
# Execute the command with the given arguments
69-
self[command](args[1:])
70-
71-
# Go no further
72-
return
73-
74-
# Execute the command
75-
self[command]()
76-
77-
def _load_auth_providers(self, providers):
78-
"""Load the given auth providers."""
79-
# Were any providers given?
80-
if not providers:
81-
82-
# Send a message about the required argument
83-
auth_commands_logger.log_message(
84-
'[SP Auth] ' + _auth_strings['Missing Load'].get_string())
85-
86-
# No need to go further
87-
return
88-
89-
# Loop through all of the given providers
90-
for provider in providers:
91-
92-
# Load the current provider
93-
self.manager.load_auth(provider)
94-
95-
_load_auth_providers.args = ['<provider>', '[provider]', '...']
96-
97-
def _unload_auth_providers(self, providers):
98-
"""Unload the given auth providers."""
99-
# Were any providers given?
100-
if not providers:
101-
102-
# Send a message about the required argument
103-
auth_commands_logger.log_message(
104-
'[SP Auth] ' + _auth_strings['Missing Unload'].get_string())
105-
106-
# No need to go further
107-
return
108-
109-
# Loop through all of the given providers
110-
for provider in providers:
111-
112-
# Unload the current provider
113-
self.manager.unload_auth(provider)
114-
115-
_unload_auth_providers.args = ['<provider>', '[provider]', '...']
116-
117-
def _reload_auth_providers(self, providers=None):
118-
"""Reload the given auth providers."""
119-
# Were any providers given?
120-
if not providers:
121-
122-
# Set providers to all currently loaded providers
123-
providers = list(self.manager)
124-
125-
# Loop through the providers
126-
for provider in providers:
127-
128-
# Reload the given provider
129-
self.manager.reload_auth(provider)
130-
131-
_reload_auth_providers.args = ['[provider]', '[provider]', '...']
132-
133-
def _print_auth_providers(self):
134-
"""List all currently loaded auth providers."""
135-
# Get header messages
136-
message = '[SP Auth] ' + _auth_strings[
137-
'Providers'].get_string() + '\n' + '=' * 61 + '\n'
138-
139-
# Loop through all loaded auth providers
140-
for provider in self.manager:
141-
142-
# Add the current provider to the message
143-
message += provider + '\n'
144-
145-
# Print ending messages
146-
auth_commands_logger.log_message(message + '=' * 61)
147-
148-
def print_auth_help(self, message=''):
149-
"""Print all "sp auth" sub-commands."""
150-
# Get header messages
151-
header = message + '[SP Auth] ' + _auth_strings[
152-
'Help'].get_string() + 'sp auth <command> [arguments]\n' + '=' * 78
153-
154-
# Print all "sp auth" sub-commands
155-
self.print_help(header, '=' * 78)
156-
157-
def print_help(self, pretext='', posttext=''):
158-
"""Print all "sp auth" sub-commands."""
159-
auth_commands_logger.log_message(
160-
pretext + '\n' + self.get_help_text() + '\n' + posttext)
161-
162-
def get_help_text(self):
163-
"""Return the help text for auth commands."""
164-
# Store the base message
165-
message = ''
166-
167-
# Loop through all registered sub-commands
168-
for item in self:
169-
170-
# Add the base text
171-
text = 'auth {0}'.format(item)
172-
173-
# Does the current item use arguments?
174-
if hasattr(self[item], 'args'):
175-
176-
# Add the arguments to the text
177-
text += ' ' + ' '.join(self[item].args)
178-
179-
# Add the doc strings
180-
message += text + self[item].__doc__.rjust(78 - len(text)) + '\n'
181-
182-
# Return the message
183-
return message.rstrip('\n')
184-
185-
186-
# =============================================================================
187-
# >> FUNCTIONS
188-
# =============================================================================
189-
# Get the _AuthCommands instance
190-
_auth_commands = _AuthCommands()
191-
192-
# Add all auth loading/unloading commands to the dictionary
193-
_auth_commands['load'] = _auth_commands._load_auth_providers
194-
_auth_commands['unload'] = _auth_commands._unload_auth_providers
195-
_auth_commands['reload'] = _auth_commands._reload_auth_providers
196-
197-
# Add all printing commands to the dictionary
198-
_auth_commands['list'] = _auth_commands._print_auth_providers
199-
_auth_commands['help'] = _auth_commands.print_auth_help
36+
if self.permission is not None:
37+
if index is not None and not PlayerEntity(index).has_permission(self.permission):
38+
return
39+
args = []
40+
for i in range(0, len(self.arguments)):
41+
if self.arguments[i] is not None and self.arguments[i] != command[i + 1]:
42+
return
43+
elif self.arguments[i] is None:
44+
args.append(command[i + 1])
45+
if self.callback is not None:
46+
self.callback(index, *args)
47+
48+
49+
class AuthCommandManager(list):
50+
def register_command(self, command, permission=None):
51+
authcommand = AuthCommand(command, permission)
52+
self.append(authcommand)
53+
return authcommand
54+
55+
56+
auth_commands = AuthCommandManager()
57+
58+
59+
@ClientCommand("auth")
60+
def auth_client_command(command, index):
61+
for authcommand in auth_commands:
62+
authcommand.test(index, command)
63+
64+
65+
@ServerCommand("auth")
66+
def auth_server_command(command):
67+
for auth_command in auth_commands:
68+
auth_command.test(None, command)
69+
70+
71+
@auth_commands.register_command("load <backend>", "sp.auth.commands.load")
72+
def load_backend_command(index, backend):
73+
if auth_manager.load_backend(backend):
74+
message = "[Auth] Loaded backend {} succesfully.".format(backend)
75+
else:
76+
message = "[Auth] Failed to load backend {}.".format(backend)
77+
if index is None:
78+
print(message)
79+
else:
80+
SayText2(message=message).send(index)

0 commit comments

Comments
 (0)