~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/cred/strcred.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.test.test_strcred -*-
 
2
#
 
3
# Copyright (c) 2007-2008 Twisted Matrix Laboratories.
 
4
# See LICENSE for details.
 
5
#
 
6
 
 
7
"""
 
8
Support for resolving command-line strings that represent different
 
9
checkers available to cred.
 
10
 
 
11
Examples:
 
12
 - passwd:/etc/passwd
 
13
 - memory:admin:asdf:user:lkj
 
14
 - unix
 
15
"""
 
16
 
 
17
import sys
 
18
 
 
19
from zope.interface import Interface, Attribute
 
20
 
 
21
from twisted.plugin import getPlugins
 
22
from twisted.python import usage
 
23
 
 
24
 
 
25
 
 
26
class ICheckerFactory(Interface):
 
27
    """
 
28
    A factory for objects which provide
 
29
    L{twisted.cred.checkers.ICredentialsChecker}.
 
30
 
 
31
    It's implemented by twistd plugins creating checkers.
 
32
    """
 
33
 
 
34
    authType = Attribute(
 
35
        'A tag that identifies the authentication method.')
 
36
 
 
37
 
 
38
    authHelp = Attribute(
 
39
        'A detailed (potentially multi-line) description of precisely '
 
40
        'what functionality this CheckerFactory provides.')
 
41
 
 
42
 
 
43
    argStringFormat = Attribute(
 
44
        'A short (one-line) description of the argument string format.')
 
45
 
 
46
 
 
47
    credentialInterfaces = Attribute(
 
48
        'A list of credentials interfaces that this factory will support.')
 
49
 
 
50
 
 
51
    def generateChecker(argstring):
 
52
        """
 
53
        Return an L{ICredentialChecker} provider using the supplied
 
54
        argument string.
 
55
        """
 
56
 
 
57
 
 
58
 
 
59
class StrcredException(Exception):
 
60
    """
 
61
    Base exception class for strcred.
 
62
    """
 
63
 
 
64
 
 
65
 
 
66
class InvalidAuthType(StrcredException):
 
67
    """
 
68
    Raised when a user provides an invalid identifier for the
 
69
    authentication plugin (known as the authType).
 
70
    """
 
71
 
 
72
 
 
73
 
 
74
class InvalidAuthArgumentString(StrcredException):
 
75
    """
 
76
    Raised by an authentication plugin when the argument string
 
77
    provided is formatted incorrectly.
 
78
    """
 
79
 
 
80
 
 
81
 
 
82
class UnsupportedInterfaces(StrcredException):
 
83
    """
 
84
    Raised when an application is given a checker to use that does not
 
85
    provide any of the application's supported credentials interfaces.
 
86
    """
 
87
 
 
88
 
 
89
 
 
90
# This will be used to warn the users whenever they view help for an
 
91
# authType that is not supported by the application.
 
92
notSupportedWarning = ("WARNING: This authType is not supported by "
 
93
                       "this application.")
 
94
 
 
95
 
 
96
 
 
97
def findCheckerFactories():
 
98
    """
 
99
    Find all objects that implement L{ICheckerFactory}.
 
100
    """
 
101
    return getPlugins(ICheckerFactory)
 
102
 
 
103
 
 
104
 
 
105
def findCheckerFactory(authType):
 
106
    """
 
107
    Find the first checker factory that supports the given authType.
 
108
    """
 
109
    for factory in findCheckerFactories():
 
110
        if factory.authType == authType:
 
111
            return factory
 
112
    raise InvalidAuthType(authType)
 
113
 
 
114
 
 
115
 
 
116
def makeChecker(description):
 
117
    """
 
118
    Returns an L{twisted.cred.checkers.ICredentialsChecker} based on the
 
119
    contents of a descriptive string. Similar to
 
120
    L{twisted.application.strports}.
 
121
    """
 
122
    if ':' in description:
 
123
        authType, argstring = description.split(':', 1)
 
124
    else:
 
125
        authType = description
 
126
        argstring = ''
 
127
    return findCheckerFactory(authType).generateChecker(argstring)
 
128
 
 
129
 
 
130
 
 
131
class AuthOptionMixin:
 
132
    """
 
133
    Defines helper methods that can be added on to any
 
134
    L{usage.Options} subclass that needs authentication.
 
135
 
 
136
    This mixin implements three new options methods:
 
137
 
 
138
    The opt_auth method (--auth) will write two new values to the
 
139
    'self' dictionary: C{credInterfaces} (a dict of lists) and
 
140
    C{credCheckers} (a list).
 
141
 
 
142
    The opt_help_auth method (--help-auth) will search for all
 
143
    available checker plugins and list them for the user; it will exit
 
144
    when finished.
 
145
 
 
146
    The opt_help_auth_type method (--help-auth-type) will display
 
147
    detailed help for a particular checker plugin.
 
148
 
 
149
    @cvar supportedInterfaces: An iterable object that returns
 
150
       credential interfaces which this application is able to support.
 
151
 
 
152
    @cvar authOutput: A writeable object to which this options class
 
153
        will send all help-related output. Default: L{sys.stdout}
 
154
    """
 
155
 
 
156
    supportedInterfaces = None
 
157
    authOutput = sys.stdout
 
158
 
 
159
 
 
160
    def supportsInterface(self, interface):
 
161
        """
 
162
        Returns whether a particular credentials interface is supported.
 
163
        """
 
164
        return (self.supportedInterfaces is None
 
165
                or interface in self.supportedInterfaces)
 
166
 
 
167
 
 
168
    def supportsCheckerFactory(self, factory):
 
169
        """
 
170
        Returns whether a checker factory will provide at least one of
 
171
        the credentials interfaces that we care about.
 
172
        """
 
173
        for interface in factory.credentialInterfaces:
 
174
            if self.supportsInterface(interface):
 
175
                return True
 
176
        return False
 
177
 
 
178
 
 
179
    def addChecker(self, checker):
 
180
        """
 
181
        Supply a supplied credentials checker to the Options class.
 
182
        """
 
183
        # First figure out which interfaces we're willing to support.
 
184
        supported = []
 
185
        if self.supportedInterfaces is None:
 
186
            supported = checker.credentialInterfaces
 
187
        else:
 
188
            for interface in checker.credentialInterfaces:
 
189
                if self.supportsInterface(interface):
 
190
                    supported.append(interface)
 
191
        if not supported:
 
192
            raise UnsupportedInterfaces(checker.credentialInterfaces)
 
193
        # If we get this far, then we know we can use this checker.
 
194
        if 'credInterfaces' not in self:
 
195
            self['credInterfaces'] = {}
 
196
        if 'credCheckers' not in self:
 
197
            self['credCheckers'] = []
 
198
        self['credCheckers'].append(checker)
 
199
        for interface in supported:
 
200
            self['credInterfaces'].setdefault(interface, []).append(checker)
 
201
 
 
202
 
 
203
    def opt_auth(self, description):
 
204
        """
 
205
        Specify an authentication method for the server.
 
206
        """
 
207
        try:
 
208
            self.addChecker(makeChecker(description))
 
209
        except UnsupportedInterfaces, e:
 
210
            raise usage.UsageError(
 
211
                'Auth plugin not supported: %s' % e.args[0])
 
212
        except InvalidAuthType, e:
 
213
            raise usage.UsageError(
 
214
                'Auth plugin not recognized: %s' % e.args[0])
 
215
        except Exception, e:
 
216
            raise usage.UsageError('Unexpected error: %s' % e)
 
217
 
 
218
 
 
219
    def _checkerFactoriesForOptHelpAuth(self):
 
220
        """
 
221
        Return a list of which authTypes will be displayed by --help-auth.
 
222
        This makes it a lot easier to test this module.
 
223
        """
 
224
        for factory in findCheckerFactories():
 
225
            for interface in factory.credentialInterfaces:
 
226
                if self.supportsInterface(interface):
 
227
                    yield factory
 
228
                    break
 
229
 
 
230
 
 
231
    def opt_help_auth(self):
 
232
        """
 
233
        Show all authentication methods available.
 
234
        """
 
235
        self.authOutput.write("Usage: --auth AuthType[:ArgString]\n")
 
236
        self.authOutput.write("For detailed help: --help-auth-type AuthType\n")
 
237
        self.authOutput.write('\n')
 
238
        # Figure out the right width for our columns
 
239
        firstLength = 0
 
240
        for factory in self._checkerFactoriesForOptHelpAuth():
 
241
            if len(factory.authType) > firstLength:
 
242
                firstLength = len(factory.authType)
 
243
        formatString = '  %%-%is\t%%s\n' % firstLength
 
244
        self.authOutput.write(formatString % ('AuthType', 'ArgString format'))
 
245
        self.authOutput.write(formatString % ('========', '================'))
 
246
        for factory in self._checkerFactoriesForOptHelpAuth():
 
247
            self.authOutput.write(
 
248
                formatString % (factory.authType, factory.argStringFormat))
 
249
        self.authOutput.write('\n')
 
250
        raise SystemExit(0)
 
251
 
 
252
 
 
253
    def opt_help_auth_type(self, authType):
 
254
        """
 
255
        Show help for a particular authentication type.
 
256
        """
 
257
        try:
 
258
            cf = findCheckerFactory(authType)
 
259
        except InvalidAuthType:
 
260
            raise usage.UsageError("Invalid auth type: %s" % authType)
 
261
        self.authOutput.write("Usage: --auth %s[:ArgString]\n" % authType)
 
262
        self.authOutput.write("ArgString format: %s\n" % cf.argStringFormat)
 
263
        self.authOutput.write('\n')
 
264
        for line in cf.authHelp.strip().splitlines():
 
265
            self.authOutput.write('  %s\n' % line.rstrip())
 
266
        self.authOutput.write('\n')
 
267
        if not self.supportsCheckerFactory(cf):
 
268
            self.authOutput.write('  %s\n' % notSupportedWarning)
 
269
            self.authOutput.write('\n')
 
270
        raise SystemExit(0)