File: cork.cpython-34.pyc

package info (click to toggle)
python-bottle-cork 0.12.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 936 kB
  • sloc: python: 6,862; makefile: 4
file content (410 lines) | stat: -rw-r--r-- 30,072 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410

@j>V@sXddlmZmZddlmZmZddlmZddlmZddl	m
Z
ddlmZm
Z
ddlmZddlmZdd	lZdd	lZdd	lZdd	lZdd	lZdd	lZejdd
ddd
fkredejdnydd	lZdZWnek
rFdZYnXyeWnek
rieZYnXddl m!Z!ejj"d
kZ#e
e$Z%Gddde&Z'Gddde'Z(Gddde)Z*Gddde)Z+Gddde&Z,ddZ-Gdd d e*Z.Gd!d"d"e*Z/Gd#d$d$e)Z0d	S)%)	b64encode	b64decode)datetime	timedelta)
MIMEMultipart)MIMEText)	getLogger)SMTPSMTP_SSL)Thread)timeNzPython >= 2.7.8 is requiredTF)JsonBackendc@seZdZdZdS)AAAExceptionz.Generic Authentication/Authorization ExceptionN)__name__
__module____qualname____doc__rr:/home/fede/newhome/projects/bottle-cork/tests/cork/cork.pyr9src@seZdZdZdS)
AuthExceptionz:Authentication Exception: incorrect username/password pairN)rrrrrrrrr>src
@seZdZdZddddddddddZddddZd	d	d
dZdddddd
ZddZddZ	ddZ
ddddZddZddZ
eddZeddZddZd d!d"d#dd$d%Zd&d'Zddd(d)d*d+Zd,d-Zdddd	d.d/Zd0d1Zddd2d3Zedd4d5Zedd6d7Zd8d9Zd:d;d<Zd=d>ZdS)?BaseCorkzAbstract classNF	localhostc		
Cs|r|}nt|||_d
|_||_|p<d|_d|_|dkrt|dddd	d
dd||_n	||_dS)a]Auth/Authorization/Accounting class

        :param directory: configuration directory
        :type directory: str.
        :param users_fname: users filename (without .json), defaults to 'users'
        :type users_fname: str.
        :param roles_fname: roles filename (without .json), defaults to 'roles'
        :type roles_fname: str.
        izbeaker.sessionPBKDF2NZusers_fnameusersZroles_fnamerolesZpending_reg_fnameregister
initializeiQ)Mailermailerpassword_reset_timeoutsession_domainsession_key_namepreferred_hashing_algorithmr_store)	selfZ	directoryZbackendemail_senderr"r&smtp_serversmtp_urlr'rrr__init__Fs				zBaseCork.__init__cCs||jjkr|jj|d}t|drG|jd}n|j|||}|r|j|ttj|jj|d<|jj	|r|j
|ndSn|r|j
|ndS)a'Check login credentials for an existing user.
        Optionally redirect the user to another page (typically /login)

        :param username: username
        :type username: str or unicode.
        :param password: cleartext password
        :type password: str.or unicode
        :param success_redirect: redirect authorized users (optional)
        :type success_redirect: str.
        :param fail_redirect: redirect unauthorized users (optional)
        :type fail_redirect: str.
        :returns: True for successful logins, else False
        hashencodeascii
last_loginTF)r)rhasattrr0_verify_password
_setup_cookiestrrutcnow
save_users	_redirect)r*usernamepasswordsuccess_redirect
fail_redirectsalted_hashZ
authenticatedrrrlogines&	

zBaseCork.loginz/logincCsty|j}|jWnItk
rb}z)tjdt||j|WYdd}~XnX|j|dS)zLog the user out, remove cookie

        :param success_redirect: redirect the user after logging out
        :type success_redirect: str.
        :param fail_redirect: redirect the user if it is not logged in
        :type fail_redirect: str.
        zException %s while logging out.N)_beaker_sessiondelete	Exceptionlogdebugreprr9)r*r<r=sessionerrrlogouts	 zBaseCork.logoutcCs|dk	r0||jjkr0tdq0n|rQ|dkrQtdn|dk	r~||jjkr~tdny
|j}Wn:tk
r|dkrtdn
|j|YnX|j|jjkrtdn|dk	r9||jjkrdS|dkr)tdn|j|n|r||jjkrUdS|dkrptdn|j|n|dk	r|jj|jj}|jj|}||krdS|dkrtd	n|j|ndS)
aEnsure the user is logged in has the required role (or higher).
        Optionally redirect the user to another page (typically /login)
        If both `username` and `role` are specified, both conditions need to be
        satisfied.
        If none is specified, any authenticated user will be authorized.
        By default, any role with higher level than `role` will be authorized;
        set fixed_role=True to prevent this.

        :param username: username (optional)
        :type username: str.
        :param role: role
        :type role: str.
        :param fixed_role: require user role to match `role` strictly
        :type fixed_role: bool.
        :param redirect: redirect unauthorized users (optional)
        :type redirect: str.
        NzNonexistent userz3A role must be specified if fixed_role has been setzRole not foundzUnauthenticated userz#Role not found for the current userz'Unauthorized access: incorrect usernamez#Unauthorized access: incorrect rolezUnauthorized access: )	r)rrr current_userrr9roler:)r*r:rJ
fixed_roler=ZcuZcurrent_lvlZ
threshold_lvlrrrrequiresJ

zBaseCork.requirecCs|jjdkr!tdn||jjkrBtdnyt|Wntk
rptdYnX||jj|<|jjdS)zCreate a new role.

        :param role: role name
        :type role: str.
        :param level: role level (0=lowest, 100=admin)
        :type level: int.
        :raises: AuthException on errors
        dz&The current user is not authorized to zThe role is already existingzThe level must be numeric.N)	rIlevelrr)r rint
ValueError
save_roles)r*rJrNrrrcreate_roles	
zBaseCork.create_rolecCsf|jjdkr!tdn||jjkrBtdn|jjj||jjdS)zyDeleta a role.

        :param role: role name
        :type role: str.
        :raises: AuthException on errors
        rMz&The current user is not authorized to zNonexistent role.N)rIrNrr)r rpoprQ)r*rJrrrdelete_roleszBaseCork.delete_roleccs6x/t|jjD]}||jj|fVqWdS)zUList roles.

        :returns: (role, role_level) generator (sorted by role)
        N)sortedr)r )r*rJrrr
list_rolesszBaseCork.list_rolescCs|std|jjdkr3tdn||jjkrTtdn||jjkrutdntt	j
}|j||}|jd}i|d6|d6|d	6|d
6|d6|d6|jj|<|jj
d
S)aCreate a new user account.
        This method is available to users with level>=100

        :param username: username
        :type username: str.
        :param role: role
        :type role: str.
        :param password: cleartext password
        :type password: str.
        :param email_addr: email address (optional)
        :type email_addr: str.
        :param description: description (free form)
        :type description: str.
        :raises: AuthException on errors
        zUsername must be provided.rMz3The current user is not authorized to create users.zUser is already existing.zNonexistent user role.r1rJr/
email_addrdesc
creation_dater2N)AssertionErrorrIrNrr)rrr r6rr7_hashdecoder8)r*r:rJr;rWdescriptiontstamphrrrcreate_users$zBaseCork.create_usercCsY|jjdkr!tdn||jjkrBtdn|j|jdS)zDelete a user account.
        This method is available to users with level>=100

        :param username: username
        :type username: str.
        :raises: Exceptions on errors
        rMz&The current user is not authorized to zNonexistent user.N)rIrNrr)rruserrA)r*r:rrrdelete_user@s
zBaseCork.delete_userccsNxGt|jjD]3}|jj|}||d|d|dfVqWdS)z{List users.

        :return: (username, role, email_addr, description) generator (sorted by
            username)
        rJrWrXN)rUr)r)r*Zundrrr
list_usersNszBaseCork.list_userscCs{|j}|jdd}|dkr6tdn|dk	rg||jjkrgt||d|Std|dS)zCurrent autenticated user

        :returns: User() instance, if authenticated
        :raises: AuthException otherwise
        r:NzUnauthenticated userrFzUnknown user: %s)r@getrr)rUser)r*rFr:rrrrIXs	zBaseCork.current_usercCsSy|jd}Wntk
r)dSYnX||jjkrOtd|ndS)zCheck if the current user is anonymous.

        :returns: True if the user is anonymous, False otherwise
        :raises: AuthException if the session username is unknown
        r:TzUnknown user: %sF)r@KeyErrorr)rr)r*r:rrruser_is_anonymousgs
	zBaseCork.user_is_anonymouscCs/|dk	r+||jjkr+t||SdS)z[Existing user

        :returns: User() instance if the user exist, None otherwise
        N)r)rrf)r*r:rrrraxs
z
BaseCork.userra2zSignup confirmationzviews/registration_email.tplc	
Ksp|std|s$td|s6td||jjkrWtdn||jjkrxtdn|jj||krtdntjj}
tt	j
}tj|d|d|d	|d
|d|
|	}|j
j||||j||}
|
jd}
i|d6|d	6|
d
6|d6|d6|d
6|jj|
<|jjdS)a]Register a new user account. An email with a registration validation
        is sent to the user.
        WARNING: this method is available to unauthenticated users

        :param username: username
        :type username: str.
        :param password: cleartext password
        :type password: str.
        :param role: role (optional), defaults to 'user'
        :type role: str.
        :param max_level: maximum role level (optional), defaults to 50
        :type max_level: int.
        :param email_addr: email address
        :type email_addr: str.
        :param subject: email subject
        :type subject: str.
        :param email_template: email template filename
        :type email_template: str.
        :param description: description (free form)
        :type description: str.
        :raises: AssertError or AAAException on errors
        zUsername must be provided.zA password must be provided.z"An email address must be provided.zUser is already existing.zNonexistent rolezUnauthorized roler:rWrJrYregistration_coder1r/rXN)rZr)rrr uuidZuuid4hexr6rr7bottletemplater$
send_emailr[r\pending_registrationsZsave_pending_registrations)r*r:r;rWrJZ	max_levelsubjectemail_templater]kwargsrjrY
email_textr_rrrr!s<	zBaseCork.registercCsy|jjj|}Wntk
r9tdYnX|d}||jjkretdni|dd6|dd6|dd6|dd6|dd6ttj	d	6|jj|<|jj
d
S)zValidate pending account registration, create a new account if
        successful.

        :param registration_code: registration code
        :type registration_code: str.
        zInvalid registration code.r:zUser is already existing.rJr/rWrXrYr2N)r)rprSrgrrrr6rr7r8)r*rjdatar:rrrvalidate_registrations

 zBaseCork.validate_registrationzPassword reset confirmationzviews/password_reset_emailc	KsA|sg|stdnx|jjjD]&\}}|d|kr.|}Pq.q.Wtdn||jjkrtdn|s|jj|jdd}|stdqn/|jj|d}||krtdn|j||}	tj|d|d|d	|	|}
|j	j
|||
dS)
aEmail the user with a link to reset his/her password
        If only one parameter is passed, fetch the other from the users
        database. If both are passed they will be matched against the users
        database as a security check.

        :param username: username
        :type username: str.
        :param email_addr: email address
        :type email_addr: str.
        :param subject: email subject
        :type subject: str.
        :param email_template: email template filename
        :type email_template: str.
        :raises: AAAException on missing username or email_addr,
            AuthException on incorrect username/email_addr pair
        z6At least `username` or `email_addr` must be specified.rWzEmail address not found.zNonexistent user.NzEmail address not available.z&Username/email address pair not found.r:
reset_code)rr)r	iteritemsrer_reset_codermrnr$ro)r*r:rWrqrrrskvZstored_email_addrrwrtrrrsend_password_reset_emails4	z"BaseCork.send_password_reset_emailcCsfyt|j}|jdd\}}}}t|}t|tdsZtt|tdsutt|tds|jd}nWn$tt	fk
rt
dYnXt||jkrt
dnt|tdst|j
|||s(t
dn|j|}|dkrRtd	n|jd
|dS)aHValidate reset_code and update the account password
        The username is extracted from the reset_code token

        :param reset_code: reset token
        :type reset_code: str.
        :param password: new password
        :type password: str.
        :raises: AuthException for invalid reset tokens, AAAException
        :r
zutf-8zInvalid reset code.zExpired reset code.NzNonexistent user.pwd)rr\splitrO
isinstancetyperZr0	TypeErrorrPrrr%r4rarupdate)r*rwr;r:rWr^r_rarrrreset_passwords&
zBaseCork.reset_passwordcs(|||||fdd}|S)ah
        Create a decorator to be used for authentication and authorization

        :param username: A resource can be protected for a specific user
        :param role: Minimum role level required for authorization
        :param fixed_role: Only this role gets authorized
        :param fail_redirect: The URL to redirect to if a login is required.
        cs"fdd}|S)Ncs@ddl}|jfdd}|S)Nrc	s/jdddd||S)Nr:rJrKr=)rL)aka)r=rKfuncrJsession_managerr:rrwrapperKs	zVBaseCork.make_auth_decorator.<locals>.auth_require.<locals>.decorator.<locals>.wrapper)	functoolswraps)rrr)r=rKrJrr:)rr	decoratorHs0zEBaseCork.make_auth_decorator.<locals>.auth_require.<locals>.decoratorr)r:rJrKr=r)r)r=rKrJr:rauth_requireFs
z2BaseCork.make_auth_decorator.<locals>.auth_requirer)r*r:rJrKr=rr)rrmake_auth_decorator:s
	zBaseCork.make_auth_decoratorcCs?|j}||d<|jdk	r1|j|_n|jdS)z+Setup cookie for a user that just logged inr:N)r@r&domain
_save_session)r*r:rFrrrr5Xs
	
zBaseCork._setup_cookiecCsp|dkr|j}n|dkr:|j||d|S|dkr\|j||d|Std|dS)zFHash username and password, generating salt value if required
        Nrsaltscryptz'Unknown hashing algorithm requested: %s)r(_hash_pbkdf2_hash_scryptRuntimeError)r*r:rrZalgorrrr[aszBaseCork._hashcCststdn|dkr3tjd}nt|dksQtdd||f}tj||}d||}t|S)zHash username and password, generating salt value if required
        Use scrypt.

        :returns: base-64 encoded str.
        z8scrypt.hash required. Please install the scrypt library.N zIncorrect salt lengthz%s%ss)	scrypt_availablerBosurandomlenrZrr/r)r:rr	cleartextr_hashedrrrroszBaseCork._hash_scryptcCs|dkrtjd}nt|ts3tt|dksQtd|jd}t|tsut|jd}t|tst|d|}tjd||ddd}d	||}t	|S)
zHash username and password, generating salt value if required
        Use PBKDF2 from Beaker

        :returns: base-64 encoded str.
        NrzIncorrect salt lengthzutf-8ssha1
Zdklenp)
rrrbytesrZrr0hashlibpbkdf2_hmacr)r:rrrr_rrrrrszBaseCork._hash_pbkdf2cCst|tdstt|}|d}t|trOt|}n|dd}|dkr|j|||}||kS|dkr|j|||}||kStd|dS)	zTVerity username/password pair against a salted hash

        :returns: bool
        rrr!psz%Unknown hashing algorithm in hash: %rN)	rrrZrrOchrrrr)r*r:rr>decodedZ	hash_typerr_rrrr4s


zBaseCork._verify_password`cCs|jjj}tr't|}nxk|D]c\}}tj|dd}tj}td|}|||kr.|jjj	|q.q.WdS)z~Purge expired registration requests.

        :param exp_time: expiration time (hours)
        :type exp_time: float.
        rYz%Y-%m-%d %H:%M:%S.%fhoursN)
r)rpitemsis_py3listrstrptimer7rrS)r*Zexp_timependingZ	uuid_coderuZcreationnowZmaxdeltarrr_purge_expired_registrationss
	z%BaseCork._purge_expired_registrationscCse|j||}dt}|jd}dj|jd|jd||f}t|S)zgenerate a reset_code token

        :param username: username
        :type username: str.
        :param email_addr: email address
        :type email_addr: str.
        :returns: Base-64 encoded token
        z%dzutf-8:)r[rr0joinr)r*r:rWr_trwrrrrys	
zBaseCork._reset_code)rrrrr.r?rHrLrRrTrVr`rbrdpropertyrIrhrar!rvr|rrr5r[staticmethodrrr4rryrrrrrCsN		)	N&
	=< 		rc@s@eZdZdddZdddddZddZdS)rfNc	Cs||_||jjjks*td||_|jjj|}|d|_|d|_|d|_|jjj|j|_	|dk	ry+|d|_
|d|_|d|_WqYqXndS)	aRepresent an authenticated user, exposing useful attributes:
        username, role, level, description, email_addr, session_creation_time,
        session_accessed_time, session_id. The session-related attributes are
        available for the current user only.

        :param username: username
        :type username: str.
        :param cork_obj: instance of :class:`Cork`
        zUnknown userrJrXrWNZ_creation_timeZ_accessed_time_id)
_corkr)rrZr:rJr]rWr rNZsession_creation_timeZsession_accessed_timeZ
session_id)r*r:Zcork_objrFZ	user_datarrrr.s
	!	




z
User.__init__cCs|j}||jjjkr-tdn|dk	rw||jjjkr]tdn||jjj|d<n|dk	r|jj||j|jjj|d<n|dk	r||jjj|d<n|jjjdS)a^Update an user account data

        :param role: change user role, if specified
        :type role: str.
        :param pwd: change user password, if specified
        :type pwd: str.
        :param email_addr: change user email address, if specified
        :type email_addr: str.
        :raises: AAAException on nonexistent user or role.
        zUser does not exist.NzNonexistent role.rJr/rW)	r:rr)rrr r[r\r8)r*rJrrWr:rrrrs		&zUser.updatecCsRy|jjjj|jWntk
r=tdYnX|jjjdS)zPDelete user account

        :raises: AAAException on nonexistent user.
        zNonexistent user.N)rr)rrSr:rgrr8)r*rrrrAs

zUser.delete)rrrr.rrArrrrrfsrfc@seZdZdS)RedirectN)rrrrrrrr!srcCst|dS)N)r)pathrrrraise_redirect%src@s@eZdZeddZeddZddZdS)CorkcCstj|dS)N)rmredirect)locationrrrr9*szCork._redirectcCstjjj|jS)zGet session)rmrequestenvironrer')r*rrrr@.szCork._beaker_sessioncCs|jjdS)N)r@save)r*rrrr3szCork._save_sessionN)rrrrr9rr@rrrrrr)src@s@eZdZeddZeddZddZdS)	FlaskCorkcCst|dS)N)r)rrrrr98szFlaskCork._redirectcCsddl}|jS)zGet sessionrN)flaskrF)r*rrrrr@<szFlaskCork._beaker_sessioncCsdS)Nr)r*rrrrBszFlaskCork._save_sessionN)rrrrr9rr@rrrrrr7src@s^eZdZddddZddZddZd	d
ZddZd
dZdS)r#TcCs:||_||_||_g|_|j||_dS)zSend emails asyncronously

        :param sender: Sender email address
        :type sender: str.
        :param smtp_server: SMTP server
        :type smtp_server: str.
        N)senderjoin_timeoutuse_threads_threads_parse_smtp_url_conf)r*rr-rrrrrr.Hs
				zMailer.__init__cCstjd|tj}|s-tdn|j}|ddkrVd|d<n|ddkrsd|d<nt|d|d<d|dkod	knstd
n|S)zParse SMTP URLaB
            (                                   # Optional protocol
                (?P<proto>smtp|starttls|ssl)    # Protocol name
                ://
            )?
            (                                   # Optional user:pass@
                (?P<user>[^:]*)                 # Match every char except ':'
                (: (?P<pass>.*) )? @            # Optional :pass
            )?
            (?P<fqdn>                           # Required FQDN on IP address
                ()|                             # Empty string
                (                               # FQDN
                    [a-zA-Z_\-]                 # First character cannot be a number
                    [a-zA-Z0-9_\-\.]{,254}
                )
                |(                              # IPv4
                    ([0-9]{1,3}\.){3}
                    [0-9]{1,3}
                 )
                |(                              # IPv6
                    \[                          # Square brackets
                        ([0-9a-f]{,4}:){1,8}
                        [0-9a-f]{,4}
                    \]
                )
            )
            (                                   # Optional :port
                :
                (?P<port>[0-9]{,5})             # Up to 5-digits port
            )?
            [/]?
            $
        zSMTP URL seems incorrectprotoNsmtpportrizIncorrect SMTP port)rematchVERBOSEr	groupdictrO)r*urlrrcrrrrVs 

 zMailer._parse_smtp_urlcCs|jdo|js%tdntd}||d<|j|d<||d<t|trs|jd}nt|d}|j||j	}t
jd	|jd|jrt
d
|jd||f}|j|jj|n|j||dS)
a'Send an email

        :param email_addr: email address
        :type email_addr: str.
        :param subject: subject
        :type subject: str.
        :param email_text: email text
        :type email_text: str.
        :raises: AAAException if smtp_server and/or sender are not set
        fqdnzSMTP server or sender not setalternativeZSubjectZFromZTozutf-8htmlzSending email using %stargetargsN)rrrrrrr0rattach	as_stringrCrDrr_sendstartrappend)r*rWrqrtmsgpartthreadrrrros"



	
zMailer.send_emailcCs{|jd}|dks)td|y|dkretjdt|jd|jd}nt|jd|jd}|dkrtjd	|j|j|jn|jd
dk	rtjd|j|jd
|jd
ntjd|j	|j
|||jtjdWn<t
k
rv}ztjd|ddWYdd}~XnXdS)zDeliver an email using SMTP

        :param email_addr: recipient
        :type email_addr: str.
        :param msg: email text
        :type msg: str.
        rrstarttlssslzIncorrect protocol: %szSetting up SSLrrzSending EHLO and STARTTLSraNzPerforming loginpassZSendingz
Email sentzError sending email: %sexc_infoT)zsmtpzstarttlszssl)rrZrCrDr
r	Zehlorr?ZsendmailrquitinforBerror)r*rWrrrFrGrrrrs,


 




!

zMailer._sendcsfddjDS)zdFlush email queue by waiting the completion of the existing threads

        :returns: None
        cs"g|]}|jjqSr)rr).0r)r*rr
<listcomp>s	zMailer.join.<locals>.<listcomp>)r)r*r)r*rrszMailer.joincCs'y|jWntk
r"YnXdS)z@Class destructor: wait for threads to terminate within a timeoutN)rr)r*rrr__del__s
zMailer.__del__N)	rrrr.rrorrrrrrrr#Fs5"%r#)1base64rrrrZemail.mime.multipartrZemail.mime.textrloggingrZsmtplibr	r
	threadingrrrmrrrsysrkversion_infoprintexitrrImportError
basestring	NameErrorr6ZbackendsrmajorrrrCrBrrobjectrrfrrrrr#rrrr<module>sN"



G