RAHHH
This commit is contained in:
250
backend/lib/python3.12/site-packages/twisted/cred/strcred.py
Normal file
250
backend/lib/python3.12/site-packages/twisted/cred/strcred.py
Normal file
@@ -0,0 +1,250 @@
|
||||
# -*- test-case-name: twisted.cred.test.test_strcred -*-
|
||||
#
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
#
|
||||
|
||||
"""
|
||||
Support for resolving command-line strings that represent different
|
||||
checkers available to cred.
|
||||
|
||||
Examples:
|
||||
- passwd:/etc/passwd
|
||||
- memory:admin:asdf:user:lkj
|
||||
- unix
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
from typing import Optional, Sequence, Type
|
||||
|
||||
from zope.interface import Attribute, Interface
|
||||
|
||||
from twisted.plugin import getPlugins
|
||||
from twisted.python import usage
|
||||
|
||||
|
||||
class ICheckerFactory(Interface):
|
||||
"""
|
||||
A factory for objects which provide
|
||||
L{twisted.cred.checkers.ICredentialsChecker}.
|
||||
|
||||
It's implemented by twistd plugins creating checkers.
|
||||
"""
|
||||
|
||||
authType = Attribute("A tag that identifies the authentication method.")
|
||||
|
||||
authHelp = Attribute(
|
||||
"A detailed (potentially multi-line) description of precisely "
|
||||
"what functionality this CheckerFactory provides."
|
||||
)
|
||||
|
||||
argStringFormat = Attribute(
|
||||
"A short (one-line) description of the argument string format."
|
||||
)
|
||||
|
||||
credentialInterfaces = Attribute(
|
||||
"A list of credentials interfaces that this factory will support."
|
||||
)
|
||||
|
||||
def generateChecker(argstring):
|
||||
"""
|
||||
Return an L{twisted.cred.checkers.ICredentialsChecker} provider using the supplied
|
||||
argument string.
|
||||
"""
|
||||
|
||||
|
||||
class StrcredException(Exception):
|
||||
"""
|
||||
Base exception class for strcred.
|
||||
"""
|
||||
|
||||
|
||||
class InvalidAuthType(StrcredException):
|
||||
"""
|
||||
Raised when a user provides an invalid identifier for the
|
||||
authentication plugin (known as the authType).
|
||||
"""
|
||||
|
||||
|
||||
class InvalidAuthArgumentString(StrcredException):
|
||||
"""
|
||||
Raised by an authentication plugin when the argument string
|
||||
provided is formatted incorrectly.
|
||||
"""
|
||||
|
||||
|
||||
class UnsupportedInterfaces(StrcredException):
|
||||
"""
|
||||
Raised when an application is given a checker to use that does not
|
||||
provide any of the application's supported credentials interfaces.
|
||||
"""
|
||||
|
||||
|
||||
# This will be used to warn the users whenever they view help for an
|
||||
# authType that is not supported by the application.
|
||||
notSupportedWarning = "WARNING: This authType is not supported by " "this application."
|
||||
|
||||
|
||||
def findCheckerFactories():
|
||||
"""
|
||||
Find all objects that implement L{ICheckerFactory}.
|
||||
"""
|
||||
return getPlugins(ICheckerFactory)
|
||||
|
||||
|
||||
def findCheckerFactory(authType):
|
||||
"""
|
||||
Find the first checker factory that supports the given authType.
|
||||
"""
|
||||
for factory in findCheckerFactories():
|
||||
if factory.authType == authType:
|
||||
return factory
|
||||
raise InvalidAuthType(authType)
|
||||
|
||||
|
||||
def makeChecker(description):
|
||||
"""
|
||||
Returns an L{twisted.cred.checkers.ICredentialsChecker} based on the
|
||||
contents of a descriptive string. Similar to
|
||||
L{twisted.application.strports}.
|
||||
"""
|
||||
if ":" in description:
|
||||
authType, argstring = description.split(":", 1)
|
||||
else:
|
||||
authType = description
|
||||
argstring = ""
|
||||
return findCheckerFactory(authType).generateChecker(argstring)
|
||||
|
||||
|
||||
class AuthOptionMixin:
|
||||
"""
|
||||
Defines helper methods that can be added on to any
|
||||
L{usage.Options} subclass that needs authentication.
|
||||
|
||||
This mixin implements three new options methods:
|
||||
|
||||
The opt_auth method (--auth) will write two new values to the
|
||||
'self' dictionary: C{credInterfaces} (a dict of lists) and
|
||||
C{credCheckers} (a list).
|
||||
|
||||
The opt_help_auth method (--help-auth) will search for all
|
||||
available checker plugins and list them for the user; it will exit
|
||||
when finished.
|
||||
|
||||
The opt_help_auth_type method (--help-auth-type) will display
|
||||
detailed help for a particular checker plugin.
|
||||
|
||||
@cvar supportedInterfaces: An iterable object that returns
|
||||
credential interfaces which this application is able to support.
|
||||
|
||||
@cvar authOutput: A writeable object to which this options class
|
||||
will send all help-related output. Default: L{sys.stdout}
|
||||
"""
|
||||
|
||||
supportedInterfaces: Optional[Sequence[Type[Interface]]] = None
|
||||
authOutput = sys.stdout
|
||||
|
||||
def supportsInterface(self, interface):
|
||||
"""
|
||||
Returns whether a particular credentials interface is supported.
|
||||
"""
|
||||
return self.supportedInterfaces is None or interface in self.supportedInterfaces
|
||||
|
||||
def supportsCheckerFactory(self, factory):
|
||||
"""
|
||||
Returns whether a checker factory will provide at least one of
|
||||
the credentials interfaces that we care about.
|
||||
"""
|
||||
for interface in factory.credentialInterfaces:
|
||||
if self.supportsInterface(interface):
|
||||
return True
|
||||
return False
|
||||
|
||||
def addChecker(self, checker):
|
||||
"""
|
||||
Supply a supplied credentials checker to the Options class.
|
||||
"""
|
||||
# First figure out which interfaces we're willing to support.
|
||||
supported = []
|
||||
if self.supportedInterfaces is None:
|
||||
supported = checker.credentialInterfaces
|
||||
else:
|
||||
for interface in checker.credentialInterfaces:
|
||||
if self.supportsInterface(interface):
|
||||
supported.append(interface)
|
||||
if not supported:
|
||||
raise UnsupportedInterfaces(checker.credentialInterfaces)
|
||||
# If we get this far, then we know we can use this checker.
|
||||
if "credInterfaces" not in self:
|
||||
self["credInterfaces"] = {}
|
||||
if "credCheckers" not in self:
|
||||
self["credCheckers"] = []
|
||||
self["credCheckers"].append(checker)
|
||||
for interface in supported:
|
||||
self["credInterfaces"].setdefault(interface, []).append(checker)
|
||||
|
||||
def opt_auth(self, description):
|
||||
"""
|
||||
Specify an authentication method for the server.
|
||||
"""
|
||||
try:
|
||||
self.addChecker(makeChecker(description))
|
||||
except UnsupportedInterfaces as e:
|
||||
raise usage.UsageError("Auth plugin not supported: %s" % e.args[0])
|
||||
except InvalidAuthType as e:
|
||||
raise usage.UsageError("Auth plugin not recognized: %s" % e.args[0])
|
||||
except Exception as e:
|
||||
raise usage.UsageError("Unexpected error: %s" % e)
|
||||
|
||||
def _checkerFactoriesForOptHelpAuth(self):
|
||||
"""
|
||||
Return a list of which authTypes will be displayed by --help-auth.
|
||||
This makes it a lot easier to test this module.
|
||||
"""
|
||||
for factory in findCheckerFactories():
|
||||
for interface in factory.credentialInterfaces:
|
||||
if self.supportsInterface(interface):
|
||||
yield factory
|
||||
break
|
||||
|
||||
def opt_help_auth(self):
|
||||
"""
|
||||
Show all authentication methods available.
|
||||
"""
|
||||
self.authOutput.write("Usage: --auth AuthType[:ArgString]\n")
|
||||
self.authOutput.write("For detailed help: --help-auth-type AuthType\n")
|
||||
self.authOutput.write("\n")
|
||||
# Figure out the right width for our columns
|
||||
firstLength = 0
|
||||
for factory in self._checkerFactoriesForOptHelpAuth():
|
||||
if len(factory.authType) > firstLength:
|
||||
firstLength = len(factory.authType)
|
||||
formatString = " %%-%is\t%%s\n" % firstLength
|
||||
self.authOutput.write(formatString % ("AuthType", "ArgString format"))
|
||||
self.authOutput.write(formatString % ("========", "================"))
|
||||
for factory in self._checkerFactoriesForOptHelpAuth():
|
||||
self.authOutput.write(
|
||||
formatString % (factory.authType, factory.argStringFormat)
|
||||
)
|
||||
self.authOutput.write("\n")
|
||||
raise SystemExit(0)
|
||||
|
||||
def opt_help_auth_type(self, authType):
|
||||
"""
|
||||
Show help for a particular authentication type.
|
||||
"""
|
||||
try:
|
||||
cf = findCheckerFactory(authType)
|
||||
except InvalidAuthType:
|
||||
raise usage.UsageError("Invalid auth type: %s" % authType)
|
||||
self.authOutput.write("Usage: --auth %s[:ArgString]\n" % authType)
|
||||
self.authOutput.write("ArgString format: %s\n" % cf.argStringFormat)
|
||||
self.authOutput.write("\n")
|
||||
for line in cf.authHelp.strip().splitlines():
|
||||
self.authOutput.write(" %s\n" % line.rstrip())
|
||||
self.authOutput.write("\n")
|
||||
if not self.supportsCheckerFactory(cf):
|
||||
self.authOutput.write(" %s\n" % notSupportedWarning)
|
||||
self.authOutput.write("\n")
|
||||
raise SystemExit(0)
|
||||
Reference in New Issue
Block a user