~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to www/apps/userservice/__init__.py

  • Committer: mattgiuca
  • Date: 2008-02-17 23:51:35 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:486
caps: Added a few new capabilities.
userservice: accept_me checks the user's agreement.
    Added create_user and update_user.
    Added comments detailing all the actions we'll need.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
# It must do its own authentication and authorization.
30
30
 
 
31
### Actions ###
 
32
 
 
33
# The one-and-only path segment to userservice determines the action being
 
34
# undertaken.
 
35
# All actions require that you are logged in.
 
36
# All actions require method = POST, unless otherwise stated.
 
37
 
 
38
# userservice/activate_me
 
39
# Required cap: None
 
40
# declaration = "I accept the IVLE Terms of Service"
 
41
# Activate the currently-logged-in user's account. Requires that "declaration"
 
42
# is as above, and that the user's state is "no_agreement".
 
43
 
 
44
# userservice/create_user
 
45
# Required cap: CAP_CREATEUSER
 
46
# Arguments are the same as the database columns for the "login" table.
 
47
# Required:
 
48
#   login, fullname, rolenm
 
49
# Optional:
 
50
#   password, nick, email, studentid
 
51
 
 
52
# TODO
 
53
# userservice/get_user
 
54
# method: May be GET
 
55
# Required cap: None to see yourself.
 
56
#   CAP_GETUSER to see another user.
 
57
# Gets the login details of a user. Returns as a JSON object.
 
58
# login = Optional login name of user to get. If omitted, get yourself.
 
59
 
 
60
# userservice/update_user
 
61
# Required cap: None to update yourself.
 
62
#   CAP_UPDATEUSER to update another user (and also more fields).
 
63
#   (This is all-powerful so should be only for admins)
 
64
# login = Optional login name of user to update. If omitted, update yourself.
 
65
# Other fields are optional, and will set the given field of the user.
 
66
# Without CAP_UPDATEUSER, you may change the following fields of yourself:
 
67
#   password, nick, email
 
68
# With CAP_UPDATEUSER, you may also change the following fields of any user:
 
69
#   password, nick, email, login, rolenm, unixid, fullname, studentid
 
70
# (You can't change "state", but see userservice/[en|dis]able_user).
 
71
 
 
72
# TODO
 
73
# userservice/enable_user
 
74
# Required cap: CAP_UPDATEUSER
 
75
# Enable a user whose account has been disabled. Does not work for
 
76
# no_agreement or pending users.
 
77
# login = Login name of user to enable.
 
78
 
 
79
# TODO
 
80
# userservice/disable_user
 
81
# Required cap: CAP_UPDATEUSER
 
82
# Disable a user's account. Does not work for no_agreement or pending users.
 
83
# login = Login name of user to disable.
 
84
 
31
85
import os
32
86
import sys
33
87
 
56
110
    else:
57
111
        path = req.path
58
112
    # The path determines which "command" we are receiving
 
113
    fields = req.get_fieldstorage()
59
114
    if req.path == "activate_me":
60
 
        handle_activate_me(req)
 
115
        handle_activate_me(req, fields)
61
116
    else:
62
117
        req.throw_error(req.HTTP_BAD_REQUEST)
63
118
 
64
 
def handle_activate_me(req):
 
119
def handle_activate_me(req, fields):
65
120
    """Create the jail, svn, etc, for the currently logged in user (this is
66
121
    put in the queue for usermgt to do).
67
122
    This will block until usermgt returns, which could take seconds to minutes
79
134
    "accepting" the terms - at least this way requires them to acknowledge
80
135
    their acceptance). It must only be called through a POST request.
81
136
    """
82
 
    db = common.db.DB()
83
 
 
84
 
    try:
85
 
        if req.method != "POST":
86
 
            req.throw_error(req.HTTP_BAD_REQUEST)
87
 
        fields = req.get_fieldstorage()
88
 
        try:
89
 
            declaration = fields.getfirst('declaration')
90
 
        except AttributeError:
91
 
            req.throw_error(req.HTTP_BAD_REQUEST)
92
 
        if declaration != USER_DECLARATION:
93
 
            req.throw_error(req.HTTP_BAD_REQUEST)
94
 
 
95
 
        # TODO: Check the DB that the user's status is "no_agreement".
96
 
        # (Both to avoid redundant calls, and to stop disabled users from
97
 
        # re-enabling their accounts).
98
 
 
99
 
        # Get the arguments for usermgt.create_user from the session
100
 
        # (The user must have already logged in to use this app)
101
 
        session = req.get_session()
102
 
        args = {
103
 
            "login": req.username,
104
 
        }
105
 
        msg = {'activate_user': args}
106
 
 
107
 
        response = chat.chat(USERMGT_HOST, USERMGT_PORT, msg, USERMGT_MAGIC,
108
 
            decode = False)
109
 
        # TODO: Figure out a way to let the user be "enabled" in this session.
110
 
        # (Would require a write to the session?)
111
 
        req.content_type = "text/plain"
112
 
        req.write(response)
113
 
    finally:
114
 
        db.close()
 
137
    if req.method != "POST":
 
138
        req.throw_error(req.HTTP_BAD_REQUEST)
 
139
    try:
 
140
        declaration = fields.getfirst('declaration')
 
141
    except AttributeError:
 
142
        req.throw_error(req.HTTP_BAD_REQUEST)
 
143
    if declaration != USER_DECLARATION:
 
144
        req.throw_error(req.HTTP_BAD_REQUEST)
 
145
 
 
146
    session = req.get_session()
 
147
    # Check that the user's status is "no_agreement".
 
148
    # (Both to avoid redundant calls, and to stop disabled users from
 
149
    # re-enabling their accounts).
 
150
    if session['state'] != "no_agreement":
 
151
        req.throw_error(req.HTTP_BAD_REQUEST)
 
152
 
 
153
    # Get the arguments for usermgt.activate_user from the session
 
154
    # (The user must have already logged in to use this app)
 
155
    args = {
 
156
        "login": req.username,
 
157
    }
 
158
    msg = {'activate_user': args}
 
159
 
 
160
    response = chat.chat(USERMGT_HOST, USERMGT_PORT, msg, USERMGT_MAGIC,
 
161
        decode = False)
 
162
    # TODO: Figure out a way to let the user be "enabled" in this session.
 
163
    # (Would require a write to the session?)
 
164
    req.content_type = "text/plain"
 
165
    req.write(response)
 
166
 
 
167
create_user_fields_required = [
 
168
    'login', 'fullname', 'rolenm'
 
169
]
 
170
create_user_fields_optional = [
 
171
    'password', 'nick', 'email', 'studentid'
 
172
]
 
173
def handle_create_user(req, fields):
 
174
    """Create a new user, whose state is no_agreement.
 
175
    This does not create the user's jail, just an entry in the database which
 
176
    allows the user to accept an agreement.
 
177
    """
 
178
    session = req.get_session()
 
179
    if req.method != "POST":
 
180
        req.throw_error(req.HTTP_BAD_REQUEST)
 
181
    # Check if this user has CAP_CREATEUSER
 
182
    if not session['role'].hasCap(caps.CAP_UPDATEUSER):
 
183
        req.throw_error(req.HTTP_FORBIDDEN)
 
184
 
 
185
    # Make a dict of fields to create
 
186
    create = {}
 
187
    for f in create_user_fields_required:
 
188
        try:
 
189
            create[f] = fields.getfirst(f)
 
190
        except AttributeError:
 
191
            req.throw_error(req.HTTP_BAD_REQUEST)
 
192
    for f in create_user_fields_optional:
 
193
        try:
 
194
            create[f] = fields.getfirst(f)
 
195
        except AttributeError:
 
196
            pass
 
197
 
 
198
    # Get the arguments for usermgt.create_user from the session
 
199
    # (The user must have already logged in to use this app)
 
200
    msg = {'create_user': create}
 
201
    # TEMP
 
202
    req.write(msg)
 
203
    return
 
204
    # END TEMP
 
205
 
 
206
    response = chat.chat(USERMGT_HOST, USERMGT_PORT, msg, USERMGT_MAGIC,
 
207
        decode = False)
 
208
    req.content_type = "text/plain"
 
209
    req.write(response)
 
210
 
 
211
update_user_fields_anyone = [
 
212
    'password', 'nick', 'email'
 
213
]
 
214
update_user_fields_admin = [
 
215
    'password', 'nick', 'email', 'login', 'rolenm', 'unixid', 'fullname',
 
216
    'studentid'
 
217
]
 
218
def handle_update_user(req, fields):
 
219
    """Update a user's account details.
 
220
    This can be done in a limited form by any user, on their own account,
 
221
    or with full powers by a user with CAP_UPDATEUSER on any account.
 
222
    """
 
223
    session = req.get_session()
 
224
    if req.method != "POST":
 
225
        req.throw_error(req.HTTP_BAD_REQUEST)
 
226
 
 
227
    # Only give full powers if this user has CAP_UPDATEUSER
 
228
    fullpowers = session['role'].hasCap(caps.CAP_UPDATEUSER)
 
229
    # List of fields that may be changed
 
230
    fieldlist = (update_user_fields_admin if fullpowers
 
231
        else update_user_fields_anyone)
 
232
 
 
233
    try:
 
234
        login = fields.getfirst('login')
 
235
        if not fullpowers and login != req.username:
 
236
            # Not allowed to edit other users
 
237
            req.throw_error(req.HTTP_FORBIDDEN)
 
238
    except AttributeError:
 
239
        # If login not specified, update yourself
 
240
        login = req.username
 
241
 
 
242
    # Make a dict of fields to update
 
243
    update = {}
 
244
    for f in fieldlist:
 
245
        try:
 
246
            update[f] = fields.getfirst(f)
 
247
        except AttributeError:
 
248
            pass
 
249
 
 
250
    # Get the arguments for usermgt.create_user from the session
 
251
    # (The user must have already logged in to use this app)
 
252
    args = {
 
253
        "login": req.username,
 
254
        "update": update,
 
255
    }
 
256
    msg = {'update_user': args}
 
257
    # TEMP
 
258
    req.write(msg)
 
259
    return
 
260
    # END TEMP
 
261
 
 
262
    response = chat.chat(USERMGT_HOST, USERMGT_PORT, msg, USERMGT_MAGIC,
 
263
        decode = False)
 
264
    req.content_type = "text/plain"
 
265
    req.write(response)