|
1
|
|
|
from pyramid.events import subscriber |
|
2
|
|
|
from pyramid.events import BeforeRender |
|
3
|
|
|
from pyramid.httpexceptions import HTTPFound |
|
4
|
|
|
from pyramid.renderers import render |
|
5
|
|
|
from pyramid.renderers import render_to_response |
|
6
|
|
|
from pyramid.response import Response |
|
7
|
|
|
from pyramid.response import FileResponse |
|
8
|
|
|
from pyramid.view import view_config, forbidden_view_config |
|
9
|
|
|
|
|
10
|
|
|
from sqlalchemy.sql import func |
|
11
|
|
|
from sqlalchemy.exc import DBAPIError, IntegrityError |
|
12
|
|
|
from sqlalchemy.orm.exc import NoResultFound |
|
13
|
|
|
|
|
14
|
|
|
from . import views_data |
|
15
|
|
|
|
|
16
|
|
|
from .models import * |
|
17
|
|
|
from .models.model import * |
|
18
|
|
|
from .models import user as __user |
|
19
|
|
|
from .models.user import User |
|
20
|
|
|
from .models.item import Item |
|
21
|
|
|
from .models.box import Box |
|
22
|
|
|
from .models.box_item import BoxItem |
|
23
|
|
|
from .models.transaction import Transaction, Deposit, CashDeposit, CCDeposit, BTCDeposit, Purchase |
|
24
|
|
|
from .models.transaction import Inventory, InventoryLineItem |
|
25
|
|
|
from .models.transaction import PurchaseLineItem, SubTransaction, SubSubTransaction |
|
26
|
|
|
from .models.account import Account, VirtualAccount, CashAccount |
|
27
|
|
|
from .models.event import Event |
|
28
|
|
|
from .models import event as __event |
|
29
|
|
|
from .models.vendor import Vendor |
|
30
|
|
|
from .models.item_vendor import ItemVendor |
|
31
|
|
|
from .models.box_vendor import BoxVendor |
|
32
|
|
|
from .models.request import Request |
|
33
|
|
|
from .models.request_post import RequestPost |
|
34
|
|
|
from .models.announcement import Announcement |
|
35
|
|
|
from .models.btcdeposit import BtcPendingDeposit |
|
36
|
|
|
from .models.receipt import Receipt |
|
37
|
|
|
from .models.pool import Pool |
|
38
|
|
|
from .models.pool_user import PoolUser |
|
39
|
|
|
|
|
40
|
|
|
from .utility import post_stripe_payment |
|
41
|
|
|
|
|
42
|
|
|
from pyramid.security import Allow, Everyone, remember, forget |
|
43
|
|
|
|
|
44
|
|
|
import chezbetty.datalayer as datalayer |
|
45
|
|
|
from .btc import Bitcoin, BTCException |
|
46
|
|
|
|
|
47
|
|
|
import uuid |
|
48
|
|
|
import math |
|
49
|
|
|
import pytz |
|
50
|
|
|
import traceback |
|
51
|
|
|
import arrow |
|
52
|
|
|
|
|
53
|
|
|
### |
|
54
|
|
|
### User Admin |
|
55
|
|
|
### |
|
56
|
|
|
|
|
57
|
|
|
|
|
58
|
|
|
### Common helper code |
|
59
|
|
|
|
|
60
|
|
|
def transaction_history_queries(request, user_or_pool): |
|
61
|
|
|
# Web library native date format: 2015/06/19 19:00 |
|
62
|
|
|
# DO NOT CHANGE: The datetimepicker has a bug and tries to parse the |
|
63
|
|
|
# prepopulated value before reading the format string, |
|
64
|
|
|
# which means you have to use its native format string |
|
65
|
|
|
TS_FORMAT = 'YYYY/MM/DD HH:mm' |
|
66
|
|
|
if 'history-end' not in request.GET: |
|
67
|
|
|
request.GET['history-end'] =\ |
|
68
|
|
|
arrow.now()\ |
|
69
|
|
|
.replace(hours=+1)\ |
|
70
|
|
|
.floor('hour')\ |
|
71
|
|
|
.format(TS_FORMAT) |
|
72
|
|
|
if 'history-start' not in request.GET: |
|
73
|
|
|
request.GET['history-start'] =\ |
|
74
|
|
|
arrow.get(request.GET['history-end'], TS_FORMAT)\ |
|
75
|
|
|
.replace(months=-1)\ |
|
76
|
|
|
.format(TS_FORMAT) |
|
77
|
|
|
|
|
78
|
|
|
start = arrow.get(request.GET['history-start'], TS_FORMAT) |
|
79
|
|
|
end = arrow.get(request.GET['history-end'], TS_FORMAT) |
|
80
|
|
|
start = start.replace(tzinfo='US/Eastern') |
|
81
|
|
|
end = end .replace(tzinfo='US/Eastern') |
|
82
|
|
|
start = start.to('utc') |
|
83
|
|
|
end = end .to('utc') |
|
84
|
|
|
|
|
85
|
|
|
query = user_or_pool.get_transactions_query() |
|
86
|
|
|
query = query\ |
|
87
|
|
|
.filter(event.Event.timestamp > start.datetime)\ |
|
88
|
|
|
.filter(event.Event.timestamp < end.datetime) |
|
89
|
|
|
|
|
90
|
|
|
for t in ('purchase', 'adjustment'): |
|
91
|
|
|
if 'history-filter-'+t in request.GET: |
|
92
|
|
|
query = query.filter(event.Event.type!=t) |
|
93
|
|
|
for t in ('cashdeposit', 'ccdeposit', 'btcdeposit'): |
|
94
|
|
|
if 'history-filter-'+t in request.GET: |
|
95
|
|
|
query = query.filter(Transaction.type!=t) |
|
96
|
|
|
transactions = query.all() |
|
97
|
|
|
|
|
98
|
|
|
withdrawls = query.filter(event.Event.type=='purchase').all() |
|
99
|
|
|
deposits = query.filter(event.Event.type=='deposit').all() |
|
100
|
|
|
adjustments = query.filter(event.Event.type=='adjustment').all() |
|
101
|
|
|
|
|
102
|
|
|
withdrawls = sum(w.amount for w in withdrawls) |
|
103
|
|
|
deposits = sum(d.amount for d in deposits) |
|
104
|
|
|
adjustments = sum(a.amount for a in adjustments) if len(adjustments) else None |
|
105
|
|
|
|
|
106
|
|
|
return {'transactions': transactions, |
|
107
|
|
|
'withdrawls': withdrawls, |
|
108
|
|
|
'deposits': deposits, |
|
109
|
|
|
'adjustments': adjustments, |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
|
|
113
|
|
|
|
|
114
|
|
|
@view_config(route_name='user_ajax_bool', |
|
115
|
|
|
permission='user') |
|
116
|
|
|
def user_ajax_bool(request): |
|
117
|
|
|
obj_str = request.matchdict['object'] |
|
118
|
|
|
obj_id = int(request.matchdict['id']) |
|
119
|
|
|
obj_field = request.matchdict['field'] |
|
120
|
|
|
obj_state = request.matchdict['state'].lower() == 'true' |
|
121
|
|
|
|
|
122
|
|
|
if obj_str == 'pool': |
|
123
|
|
|
obj = Pool.from_id(obj_id) |
|
124
|
|
|
obj_owner_id = obj.owner |
|
125
|
|
|
elif obj_str == 'pool_user': |
|
126
|
|
|
obj = PoolUser.from_id(obj_id) |
|
127
|
|
|
obj_owner_id = obj.pool.owner |
|
128
|
|
|
elif obj_str == 'request_post': |
|
129
|
|
|
obj = RequestPost.from_id(obj_id) |
|
130
|
|
|
obj_owner_id = obj.user_id |
|
131
|
|
|
else: |
|
132
|
|
|
# Return an error, object type not recognized |
|
133
|
|
|
request.response.status = 502 |
|
134
|
|
|
return request.response |
|
135
|
|
|
|
|
136
|
|
|
if obj_owner_id != request.user.id: |
|
137
|
|
|
request.response.status = 502 |
|
138
|
|
|
return request.response |
|
139
|
|
|
|
|
140
|
|
|
setattr(obj, obj_field, obj_state) |
|
141
|
|
|
DBSession.flush() |
|
142
|
|
|
|
|
143
|
|
|
return request.response |
|
144
|
|
|
|
|
145
|
|
|
@view_config(route_name='user_index', |
|
146
|
|
|
renderer='templates/user/index.jinja2', |
|
147
|
|
|
permission='user') |
|
148
|
|
|
def user_index(request): |
|
149
|
|
|
r = transaction_history_queries(request, request.user) |
|
150
|
|
|
r['user'] = request.user |
|
151
|
|
|
r['my_pools'] = Pool.all_by_owner(request.user) |
|
152
|
|
|
|
|
153
|
|
|
return r |
|
154
|
|
|
|
|
155
|
|
|
@view_config(route_name='user_index_slash', |
|
156
|
|
|
renderer='templates/user/index.jinja2', |
|
157
|
|
|
permission='user') |
|
158
|
|
|
def user_index_slash(request): |
|
159
|
|
|
return HTTPFound(location=request.route_url('user_index')) |
|
160
|
|
|
|
|
161
|
|
|
@view_config(route_name='user_deposit_cc', |
|
162
|
|
|
renderer='templates/user/deposit_cc.jinja2', |
|
163
|
|
|
permission='user') |
|
164
|
|
|
def user_deposit_cc(request): |
|
165
|
|
|
pools = Pool.all_accessable(request.user, True) |
|
166
|
|
|
pool = None |
|
167
|
|
|
if 'acct' in request.GET: |
|
168
|
|
|
account = request.GET['acct'] |
|
169
|
|
|
if account != 'user': |
|
170
|
|
|
pool = Pool.from_id(account.split('-')[1]) |
|
171
|
|
|
else: |
|
172
|
|
|
account = 'user' |
|
173
|
|
|
return {'user': request.user, |
|
174
|
|
|
'account': account, |
|
175
|
|
|
'pool': pool, |
|
176
|
|
|
'pools': pools, |
|
177
|
|
|
'stripe_pk': request.registry.settings['stripe.publishable_key'], |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
@view_config(route_name='user_deposit_cc_custom', |
|
181
|
|
|
renderer='templates/user/deposit_cc_custom.jinja2', |
|
182
|
|
|
permission='user') |
|
183
|
|
|
def user_deposit_cc_custom(request): |
|
184
|
|
|
account = request.GET['betty_to_account'] |
|
185
|
|
|
if account != 'user': |
|
186
|
|
|
pool = Pool.from_id(account.split('-')[1]) |
|
187
|
|
|
else: |
|
188
|
|
|
pool = None |
|
189
|
|
|
return {'user': request.user, |
|
190
|
|
|
'stripe_pk': request.registry.settings['stripe.publishable_key'], |
|
191
|
|
|
'amount': round(Decimal(request.GET['deposit-amount']), 2), |
|
192
|
|
|
'account': account, |
|
193
|
|
|
'pool': pool, |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
@view_config(route_name='user_deposit_cc_submit', |
|
197
|
|
|
request_method='POST', |
|
198
|
|
|
permission='user') |
|
199
|
|
|
def user_deposit_cc_submit(request): |
|
200
|
|
|
token = request.POST['stripeToken'] |
|
201
|
|
|
amount = Decimal(request.POST['betty_amount']) |
|
202
|
|
|
total_cents = int(request.POST['betty_total_cents']) |
|
203
|
|
|
to_account = request.POST['betty_to_account'] |
|
204
|
|
|
|
|
205
|
|
|
try: |
|
206
|
|
|
if to_account != 'user': |
|
207
|
|
|
pool = Pool.from_id(to_account.split('-')[1]) |
|
208
|
|
|
if pool.enabled == False: |
|
209
|
|
|
print("to_account:", to_account) |
|
210
|
|
|
raise NotImplementedError |
|
211
|
|
|
if pool.owner != request.user.id: |
|
212
|
|
|
if pool not in map(lambda pu: getattr(pu, 'pool'), request.user.pools): |
|
213
|
|
|
print("to_account:", to_account) |
|
214
|
|
|
raise NotImplementedError |
|
215
|
|
|
except Exception as e: |
|
216
|
|
|
traceback.print_exc() |
|
217
|
|
|
request.session.flash('Unexpected error processing transaction. Card NOT charged.', 'error') |
|
218
|
|
|
return HTTPFound(location=request.route_url('user_index')) |
|
219
|
|
|
|
|
220
|
|
|
post_stripe_payment( |
|
221
|
|
|
datalayer, |
|
222
|
|
|
request, |
|
223
|
|
|
token, |
|
224
|
|
|
amount, |
|
225
|
|
|
total_cents, |
|
226
|
|
|
request.user, |
|
227
|
|
|
request.user if to_account == 'user' else pool, |
|
228
|
|
|
) |
|
229
|
|
|
|
|
230
|
|
|
return HTTPFound(location=request.route_url('user_index')) |
|
231
|
|
|
|
|
232
|
|
|
|
|
233
|
|
|
|
|
234
|
|
|
@view_config(route_name='user_item_list', |
|
235
|
|
|
renderer='templates/user/item_list.jinja2', |
|
236
|
|
|
permission='user') |
|
237
|
|
|
def item_list(request): |
|
238
|
|
|
items = DBSession.query(Item)\ |
|
239
|
|
|
.filter(Item.enabled==True)\ |
|
240
|
|
|
.filter(Item.in_stock>0)\ |
|
241
|
|
|
.order_by(Item.name).all() |
|
242
|
|
|
out_of_stock_items = DBSession.query(Item)\ |
|
243
|
|
|
.filter(Item.enabled==True)\ |
|
244
|
|
|
.filter(Item.in_stock==0)\ |
|
245
|
|
|
.order_by(Item.name).all() |
|
246
|
|
View Code Duplication |
disabled_items = DBSession.query(Item)\ |
|
|
|
|
|
|
247
|
|
|
.filter(Item.enabled==False)\ |
|
248
|
|
|
.order_by(Item.name).all() |
|
249
|
|
|
return {'items': items, |
|
250
|
|
|
'out_of_stock_items': out_of_stock_items, |
|
251
|
|
|
'disabled_items': disabled_items} |
|
252
|
|
|
|
|
253
|
|
|
|
|
254
|
|
|
@view_config(route_name='user_ajax_item_request_fuzzy', |
|
255
|
|
|
renderer='templates/user/item_request_fuzzy.jinja2', |
|
256
|
|
|
permission='user') |
|
257
|
|
|
def item_request_fuzzy(request): |
|
258
|
|
|
new_item = request.POST['new_item'] |
|
259
|
|
|
matches = DBSession.query(Item)\ |
|
260
|
|
|
.filter(Item.name.ilike('%'+new_item+'%'))\ |
|
261
|
|
|
.order_by(Item.name) |
|
262
|
|
|
enabled = matches.filter(Item.enabled==True) |
|
263
|
|
|
in_stock = enabled.filter(Item.in_stock>0).all() |
|
264
|
|
|
out_of_stock = enabled.filter(Item.in_stock==0).all() |
|
265
|
|
|
for item in out_of_stock: |
|
266
|
|
|
purchase = SubTransaction.all_item_purchases(item.id, limit=1)[0] |
|
267
|
|
|
item.most_recent_purchase = purchase |
|
268
|
|
|
disabled = matches.filter(Item.enabled==False).all() |
|
269
|
|
|
return { |
|
270
|
|
|
'in_stock': in_stock, |
|
271
|
|
|
'out_of_stock': out_of_stock, |
|
272
|
|
View Code Duplication |
'disabled': disabled, |
|
|
|
|
|
|
273
|
|
|
} |
|
274
|
|
|
|
|
275
|
|
|
|
|
276
|
|
|
@view_config(route_name='user_item_request', |
|
277
|
|
|
renderer='templates/user/item_request.jinja2', |
|
278
|
|
|
permission='user') |
|
279
|
|
|
def item_request(request): |
|
280
|
|
|
requests = Request.all() |
|
281
|
|
|
vendors = Vendor.all() |
|
282
|
|
|
return { |
|
283
|
|
|
'requests': requests, |
|
284
|
|
|
'vendors': vendors, |
|
285
|
|
|
} |
|
286
|
|
|
|
|
287
|
|
|
|
|
288
|
|
|
@view_config(route_name='user_item_request_new', |
|
289
|
|
|
request_method='POST', |
|
290
|
|
|
permission='user') |
|
291
|
|
|
def item_request_new(request): |
|
292
|
|
|
try: |
|
293
|
|
|
request_text = request.POST['request'] |
|
294
|
|
|
vendor_id = request.POST['vendor'] |
|
295
|
|
|
vendor = Vendor.from_id(vendor_id) |
|
296
|
|
|
vendor_url = request.POST['vendor-url'] |
|
297
|
|
|
if len(request_text) < 5: |
|
298
|
|
|
raise ValueError() |
|
299
|
|
|
|
|
300
|
|
|
datalayer.new_request(request.user, request_text, vendor, vendor_url) |
|
301
|
|
|
|
|
302
|
|
|
request.session.flash('Request added successfully', 'success') |
|
303
|
|
|
return HTTPFound(location=request.route_url('user_item_request')) |
|
304
|
|
|
|
|
305
|
|
|
except ValueError: |
|
306
|
|
|
request.session.flash('Please include a detailed description of the item.', 'error') |
|
307
|
|
|
return HTTPFound(location=request.route_url('user_item_request')) |
|
308
|
|
|
|
|
309
|
|
|
except: |
|
310
|
|
|
request.session.flash('Error adding request.', 'error') |
|
311
|
|
|
return HTTPFound(location=request.route_url('user_item_request')) |
|
312
|
|
|
|
|
313
|
|
|
|
|
314
|
|
|
@view_config(route_name='user_item_request_post_new', |
|
315
|
|
|
request_method='POST', |
|
316
|
|
|
permission='user') |
|
317
|
|
|
def item_request_post_new(request): |
|
318
|
|
|
try: |
|
319
|
|
|
item_request = Request.from_id(request.matchdict['id']) |
|
320
|
|
|
post_text = request.POST['post'] |
|
321
|
|
|
if post_text.strip() == '': |
|
322
|
|
|
request.session.flash('Empty comment not saved.', 'error') |
|
323
|
|
|
return HTTPFound(location=request.route_url('user_item_request')) |
|
324
|
|
|
post = RequestPost(item_request, request.user, post_text) |
|
325
|
|
|
DBSession.add(post) |
|
326
|
|
|
DBSession.flush() |
|
327
|
|
|
except Exception as e: |
|
328
|
|
|
if request.debug: |
|
329
|
|
|
raise(e) |
|
330
|
|
|
else: |
|
331
|
|
|
print(e) |
|
332
|
|
|
request.session.flash('Error posting comment.', 'error') |
|
333
|
|
|
return HTTPFound(location=request.route_url('user_item_request')) |
|
334
|
|
|
|
|
335
|
|
|
|
|
336
|
|
|
|
|
337
|
|
|
|
|
338
|
|
|
@view_config(route_name='user_pools', |
|
339
|
|
|
renderer='templates/user/pools.jinja2', |
|
340
|
|
|
permission='user') |
|
341
|
|
|
def user_pools(request): |
|
342
|
|
|
return {'user': request.user, |
|
343
|
|
|
'my_pools': Pool.all_by_owner(request.user)} |
|
344
|
|
|
|
|
345
|
|
|
|
|
346
|
|
|
@view_config(route_name='user_pools_new_submit', |
|
347
|
|
|
request_method='POST', |
|
348
|
|
|
permission='user') |
|
349
|
|
|
def user_pools_new_submit(request): |
|
350
|
|
|
try: |
|
351
|
|
|
pool_name = request.POST['pool-name'].strip() |
|
352
|
|
|
if len(pool_name) > 255: |
|
353
|
|
|
pool_name = pool_name[0:255] |
|
354
|
|
|
if len(pool_name) < 5: |
|
355
|
|
|
request.session.flash('Pool names must be at least 5 letters long', 'error') |
|
356
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
357
|
|
|
|
|
358
|
|
|
pool = Pool(request.user, pool_name) |
|
359
|
|
|
DBSession.add(pool) |
|
360
|
|
|
DBSession.flush() |
|
361
|
|
|
|
|
362
|
|
|
request.session.flash('Pool created.', 'succcess') |
|
363
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
364
|
|
|
|
|
365
|
|
|
except Exception as e: |
|
366
|
|
|
if request.debug: raise(e) |
|
367
|
|
|
request.session.flash('Error creating pool.', 'error') |
|
368
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
369
|
|
|
|
|
370
|
|
|
|
|
371
|
|
View Code Duplication |
@view_config(route_name='user_pool', |
|
|
|
|
|
|
372
|
|
|
renderer='templates/user/pool.jinja2', |
|
373
|
|
|
permission='user') |
|
374
|
|
|
def user_pool(request): |
|
375
|
|
|
try: |
|
376
|
|
|
pool = Pool.from_id(request.matchdict['pool_id']) |
|
377
|
|
|
if pool.owner != request.user.id: |
|
378
|
|
|
request.session.flash('You do not have permission to view that pool.', 'error') |
|
379
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
380
|
|
|
|
|
381
|
|
|
r = transaction_history_queries(request, pool) |
|
382
|
|
|
r['user'] = request.user |
|
383
|
|
|
r['pool'] = pool |
|
384
|
|
|
|
|
385
|
|
|
return r |
|
386
|
|
|
except Exception as e: |
|
387
|
|
|
if request.debug: raise(e) |
|
388
|
|
|
request.session.flash('Could not load pool.', 'error') |
|
389
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
390
|
|
|
|
|
391
|
|
|
|
|
392
|
|
|
@view_config(route_name='user_pool_addmember_submit', |
|
393
|
|
|
request_method='POST', |
|
394
|
|
|
permission='user') |
|
395
|
|
|
def user_pool_addmember_submit(request): |
|
396
|
|
|
try: |
|
397
|
|
|
pool = Pool.from_id(request.POST['pool-id']) |
|
398
|
|
|
if pool.owner != request.user.id: |
|
399
|
|
|
request.session.flash('You do not have permission to view that pool.', 'error') |
|
400
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
401
|
|
|
|
|
402
|
|
|
# Look up the user that is being added to the pool |
|
403
|
|
|
user = User.from_uniqname(request.POST['uniqname'].strip(), True) |
|
404
|
|
|
if user == None: |
|
405
|
|
|
request.session.flash('Could not find that user.', 'error') |
|
406
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
407
|
|
|
|
|
408
|
|
|
# Can't add yourself |
|
409
|
|
|
if user.id == pool.owner: |
|
410
|
|
|
request.session.flash('You cannot add yourself to a pool. By owning the pool you are automatically a part of it.', 'error') |
|
411
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
412
|
|
|
|
|
413
|
|
|
# Make sure the user isn't already in the pool |
|
414
|
|
|
for u in pool.users: |
|
415
|
|
|
if u.user_id == user.id: |
|
416
|
|
|
request.session.flash('User is already in pool.', 'error') |
|
417
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
418
|
|
|
|
|
419
|
|
|
# Add the user to the pool |
|
420
|
|
|
pooluser = PoolUser(pool, user) |
|
421
|
|
|
DBSession.add(pooluser) |
|
422
|
|
|
DBSession.flush() |
|
423
|
|
|
|
|
424
|
|
|
request.session.flash('{} added to the pool.'.format(user.name), 'succcess') |
|
425
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
426
|
|
|
|
|
427
|
|
|
except Exception as e: |
|
428
|
|
|
if request.debug: raise(e) |
|
429
|
|
|
request.session.flash('Error adding user to pool.', 'error') |
|
430
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
431
|
|
|
|
|
432
|
|
|
|
|
433
|
|
|
@view_config(route_name='user_pool_changename_submit', |
|
434
|
|
|
request_method='POST', |
|
435
|
|
|
permission='user') |
|
436
|
|
|
def user_pool_changename_submit(request): |
|
437
|
|
|
try: |
|
438
|
|
|
pool = Pool.from_id(request.POST['pool-id']) |
|
439
|
|
|
if pool.owner != request.user.id: |
|
440
|
|
|
request.session.flash('You do not have permission to view that pool.', 'error') |
|
441
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
442
|
|
|
|
|
443
|
|
|
pool_name = request.POST['newname'].strip() |
|
444
|
|
|
if len(pool_name) > 255: |
|
445
|
|
|
pool_name = pool_name[0:255] |
|
446
|
|
|
if len(pool_name) < 5: |
|
447
|
|
|
request.session.flash('Pool names must be at least 5 letters long', 'error') |
|
448
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=int(pool.id))) |
|
449
|
|
|
|
|
450
|
|
|
pool.name = pool_name |
|
451
|
|
|
|
|
452
|
|
|
request.session.flash('Pool created.', 'succcess') |
|
453
|
|
|
return HTTPFound(location=request.route_url('user_pool', pool_id=pool.id)) |
|
454
|
|
|
except Exception as e: |
|
455
|
|
|
if request.debug: raise(e) |
|
456
|
|
|
request.session.flash('Error changing pool name.', 'error') |
|
457
|
|
|
return HTTPFound(location=request.route_url('user_pools')) |
|
458
|
|
|
|
|
459
|
|
|
|
|
460
|
|
|
@view_config(route_name='user_password_edit', |
|
461
|
|
|
renderer='templates/user/password_edit.jinja2', |
|
462
|
|
|
permission='user') |
|
463
|
|
|
def user_password_edit(request): |
|
464
|
|
|
return {} |
|
465
|
|
|
|
|
466
|
|
|
|
|
467
|
|
View Code Duplication |
@view_config(route_name='user_password_edit_submit', |
|
|
|
|
|
|
468
|
|
|
request_method='POST', |
|
469
|
|
|
permission='user') |
|
470
|
|
|
def user_password_edit_submit(request): |
|
471
|
|
|
pwd0 = request.POST['edit-password-0'] |
|
472
|
|
|
pwd1 = request.POST['edit-password-1'] |
|
473
|
|
|
if pwd0 != pwd1: |
|
474
|
|
|
request.session.flash('Error: Passwords do not match', 'error') |
|
475
|
|
|
return HTTPFound(location=request.route_url('user_password_edit')) |
|
476
|
|
|
request.user.password = pwd0 |
|
477
|
|
|
request.session.flash('Password changed successfully.', 'success') |
|
478
|
|
|
return HTTPFound(location=request.route_url('user_index')) |
|
479
|
|
|
# check that changing password for actually logged in user |
|
480
|
|
|
|
|
481
|
|
|
|
|
482
|
|
|
|