~launchpad-pqm/launchpad/devel

10693.3.1 by Jonathan Lange
Split the events classes into their own module.
1
# Copyright 2010 Canonical Ltd.  This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
4
"""Events generated by the SSH server."""
5
6
__metaclass__ = type
7
__all__ = [
8
    'AuthenticationFailed',
10693.5.10 by Jonathan Lange
Move the BazaarSSH events back to codehosting.
9
    'AvatarEvent',
10693.3.1 by Jonathan Lange
Split the events classes into their own module.
10
    'ILoggingEvent',
11
    'LoggingEvent',
12
    'ServerStarting',
13
    'ServerStopped',
14
    'SFTPClosed',
15
    'SFTPStarted',
16
    'UserConnected',
17
    'UserDisconnected',
18
    'UserLoggedIn',
19
    'UserLoggedOut',
20
    ]
21
22
import logging
23
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
24
from zope.interface import (
25
    Attribute,
26
    implements,
27
    Interface,
28
    )
10693.3.1 by Jonathan Lange
Split the events classes into their own module.
29
30
31
class ILoggingEvent(Interface):
32
    """An event is a logging event if it has a message and a severity level.
33
10693.5.11 by Jonathan Lange
Clean up some references to codehosting.
34
    Events that provide this interface will be logged in the SSH server access
10693.3.1 by Jonathan Lange
Split the events classes into their own module.
35
    log.
36
    """
37
38
    level = Attribute("The level to log the event at.")
39
    message = Attribute("The message to log.")
40
41
42
class LoggingEvent:
43
    """An event that can be logged to a Python logger.
44
45
    :ivar level: The level to log itself as. This should be defined as a
46
        class variable in subclasses.
47
    :ivar template: The format string of the message to log. This should be
48
        defined as a class variable in subclasses.
49
    """
50
51
    implements(ILoggingEvent)
52
53
    def __init__(self, level=None, template=None, **data):
54
        """Construct a logging event.
55
56
        :param level: The level to log the event as. If specified, overrides
57
            the 'level' class variable.
58
        :param template: The format string of the message to log. If
59
            specified, overrides the 'template' class variable.
60
        :param **data: Information to be logged. Entries will be substituted
61
            into the template and stored as attributes.
62
        """
63
        if level is not None:
64
            self._level = level
65
        if template is not None:
66
            self.template = template
67
        self._data = data
68
69
    @property
70
    def level(self):
71
        """See `ILoggingEvent`."""
72
        return self._level
73
74
    @property
75
    def message(self):
76
        """See `ILoggingEvent`."""
77
        return self.template % self._data
78
79
80
class ServerStarting(LoggingEvent):
81
82
    level = logging.INFO
83
    template = '---- Server started ----'
84
85
86
class ServerStopped(LoggingEvent):
87
88
    level = logging.INFO
89
    template = '---- Server stopped ----'
90
91
92
class UserConnected(LoggingEvent):
93
94
    level = logging.INFO
95
    template = '[%(session_id)s] %(address)s connected.'
96
97
    def __init__(self, transport, address):
98
        LoggingEvent.__init__(
99
            self, session_id=id(transport), address=address)
100
101
102
class AuthenticationFailed(LoggingEvent):
103
104
    level = logging.INFO
105
    template = '[%(session_id)s] failed to authenticate.'
106
107
    def __init__(self, transport):
108
        LoggingEvent.__init__(self, session_id=id(transport))
109
110
111
class UserDisconnected(LoggingEvent):
112
113
    level = logging.INFO
114
    template = '[%(session_id)s] disconnected.'
115
116
    def __init__(self, transport):
117
        LoggingEvent.__init__(self, session_id=id(transport))
118
119
120
class AvatarEvent(LoggingEvent):
121
    """Base avatar event."""
122
123
    level = logging.INFO
124
125
    def __init__(self, avatar):
126
        self.avatar = avatar
127
        LoggingEvent.__init__(
128
            self, session_id=id(avatar.transport), username=avatar.username)
129
130
131
class UserLoggedIn(AvatarEvent):
132
133
    template = '[%(session_id)s] %(username)s logged in.'
134
135
136
class UserLoggedOut(AvatarEvent):
137
138
    template = '[%(session_id)s] %(username)s disconnected.'
139
140
141
class SFTPStarted(AvatarEvent):
142
143
    template = '[%(session_id)s] %(username)s started SFTP session.'
144
145
146
class SFTPClosed(AvatarEvent):
147
148
    template = '[%(session_id)s] %(username)s closed SFTP session.'