pyramid-fullauth 0.3.2__py2.7.egg → 0.5.0__py2.7.egg

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. EGG-INFO/PKG-INFO +41 -10
  2. EGG-INFO/SOURCES.txt +2 -0
  3. EGG-INFO/requires.txt +4 -6
  4. pyramid_fullauth/__init__.py +3 -3
  5. pyramid_fullauth/__init__.pyc +0 -0
  6. pyramid_fullauth/auth.py +2 -1
  7. pyramid_fullauth/auth.pyc +0 -0
  8. pyramid_fullauth/compat.py +18 -0
  9. pyramid_fullauth/compat.pyc +0 -0
  10. pyramid_fullauth/events.py +0 -1
  11. pyramid_fullauth/events.pyc +0 -0
  12. pyramid_fullauth/exceptions.pyc +0 -0
  13. pyramid_fullauth/models/__init__.py +5 -4
  14. pyramid_fullauth/models/__init__.pyc +0 -0
  15. pyramid_fullauth/models/extensions/__init__.py +39 -0
  16. pyramid_fullauth/models/extensions/__init__.pyc +0 -0
  17. pyramid_fullauth/models/mixins/__init__.pyc +0 -0
  18. pyramid_fullauth/models/mixins/email.py +53 -6
  19. pyramid_fullauth/models/mixins/email.pyc +0 -0
  20. pyramid_fullauth/models/mixins/password.pyc +0 -0
  21. pyramid_fullauth/request.py +5 -4
  22. pyramid_fullauth/request.pyc +0 -0
  23. pyramid_fullauth/resources/helpers/social.mako +3 -3
  24. pyramid_fullauth/resources/locale/pyramid_fullauth.pot +23 -23
  25. pyramid_fullauth/routing/__init__.pyc +0 -0
  26. pyramid_fullauth/routing/predicates.pyc +0 -0
  27. pyramid_fullauth/tools.py +6 -3
  28. pyramid_fullauth/tools.pyc +0 -0
  29. pyramid_fullauth/views/__init__.pyc +0 -0
  30. pyramid_fullauth/views/basic/__init__.pyc +0 -0
  31. pyramid_fullauth/views/basic/activate.pyc +0 -0
  32. pyramid_fullauth/views/basic/forbidden.py +2 -3
  33. pyramid_fullauth/views/basic/forbidden.pyc +0 -0
  34. pyramid_fullauth/views/basic/login.py +7 -7
  35. pyramid_fullauth/views/basic/login.pyc +0 -0
  36. pyramid_fullauth/views/basic/logout.pyc +0 -0
  37. pyramid_fullauth/views/basic/profile/__init__.pyc +0 -0
  38. pyramid_fullauth/views/basic/profile/email.py +2 -1
  39. pyramid_fullauth/views/basic/profile/email.pyc +0 -0
  40. pyramid_fullauth/views/basic/profile/password.py +5 -4
  41. pyramid_fullauth/views/basic/profile/password.pyc +0 -0
  42. pyramid_fullauth/views/basic/register.py +7 -6
  43. pyramid_fullauth/views/basic/register.pyc +0 -0
  44. pyramid_fullauth/views/social.py +6 -3
  45. pyramid_fullauth/views/social.pyc +0 -0
  46. tests/__init__.pyc +0 -0
  47. tests/conftest.py +2 -1
  48. tests/conftest.pyc +0 -0
  49. tests/tools.pyc +0 -0
  50. tests/unit/test_default_settings.pyc +0 -0
  51. tests/unit/test_groupfinder.pyc +0 -0
  52. tests/unit/test_social_view.py +28 -26
  53. tests/unit/test_social_view.pyc +0 -0
  54. tests/unit/test_tools.pyc +0 -0
  55. tests/unit/test_user_active.pyc +0 -0
  56. tests/unit/test_user_admin.pyc +0 -0
  57. tests/unit/test_user_email.pyc +0 -0
  58. tests/unit/test_user_password.py +1 -1
  59. tests/unit/test_user_password.pyc +0 -0
  60. tests/unit/test_user_providers.pyc +0 -0
  61. tests/unit/test_user_repr.py +2 -2
  62. tests/unit/test_user_repr.pyc +0 -0
  63. tests/unit/test_validators.py +1 -1
  64. tests/unit/test_validators.pyc +0 -0
  65. tests/views/__init__.pyc +0 -0
  66. tests/views/conftest.py +5 -0
  67. tests/views/conftest.pyc +0 -0
  68. tests/views/test_activation.py +13 -6
  69. tests/views/test_activation.pyc +0 -0
  70. tests/views/test_email.py +2 -2
  71. tests/views/test_email.pyc +0 -0
  72. tests/views/test_events.py +36 -33
  73. tests/views/test_events.pyc +0 -0
  74. tests/views/test_login.py +23 -2
  75. tests/views/test_login.pyc +0 -0
  76. tests/views/test_login_social.py +97 -69
  77. tests/views/test_login_social.pyc +0 -0
  78. tests/views/test_logout.pyc +0 -0
  79. tests/views/test_register.py +9 -5
  80. tests/views/test_register.pyc +0 -0
  81. tests/views/test_reset.py +9 -4
  82. tests/views/test_reset.pyc +0 -0
tests/views/test_login.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Log in related test."""
2
2
  import pytest
3
+ import transaction
4
+
3
5
  from tests.tools import authenticate, is_user_logged, DEFAULT_USER
4
6
 
5
7
 
@@ -23,7 +25,11 @@ def test_login_view_secret(extended_app):
23
25
  assert 'email' in res.form.fields
24
26
 
25
27
 
26
- def test_login(active_user, extended_app):
28
+ @pytest.mark.parametrize('email', (
29
+ DEFAULT_USER['email'].lower(),
30
+ DEFAULT_USER['email'].upper()
31
+ ))
32
+ def test_login_ok(active_user, extended_app, email):
27
33
  """Actually log in test."""
28
34
  res = extended_app.get('/secret', status=302)
29
35
  res = res.follow()
@@ -31,7 +37,7 @@ def test_login(active_user, extended_app):
31
37
 
32
38
  assert is_user_logged(extended_app) is False
33
39
 
34
- res = authenticate(extended_app)
40
+ res = authenticate(extended_app, email=email)
35
41
  assert 'Max-Age=' not in str(res)
36
42
 
37
43
  assert is_user_logged(extended_app) is True
@@ -149,3 +155,18 @@ def test_default_login_redirectaway(active_user, authable_app):
149
155
  authenticate(authable_app)
150
156
  res = authable_app.get('/login', status=303)
151
157
  assert res.location == 'http://localhost/'
158
+
159
+
160
+ def test_login_invalid_cookie(db_session, active_user, extended_app):
161
+ """Test access login page by deleted user."""
162
+ res = authenticate(extended_app)
163
+ assert 'Max-Age=' not in str(res)
164
+
165
+ assert is_user_logged(extended_app) is True
166
+
167
+ db_session.delete(active_user)
168
+ transaction.commit()
169
+
170
+ # will rise Attribute error
171
+ res = extended_app.get('/login')
172
+ assert res.status_code == 200, "Should stay since user is no longer valid!"
Binary file
@@ -1,43 +1,54 @@
1
1
  """Social network login test."""
2
2
  import transaction
3
3
  from pyramid import testing
4
- from velruse import AuthenticationComplete
4
+ from pyramid.compat import text_type
5
5
  from mock import MagicMock
6
6
 
7
+ from velruse import AuthenticationComplete
7
8
  from pyramid_fullauth.views.social import SocialLoginViews
9
+
8
10
  from pyramid_fullauth.models import User
11
+ from pyramid_fullauth.compat import urlparse, parse_qs
12
+
13
+ from tests.views.conftest import mock_translate
9
14
 
10
15
 
11
16
  def test_social_login_link(social_app):
12
17
  """Login:Form displayed social form."""
13
18
  res = social_app.get('/login')
14
- assert ('Connect with facebook</a>' in res.body)
19
+ assert ('Connect with facebook</a>' in res.body.decode('unicode_escape'))
15
20
 
16
21
 
17
22
  def test_social_click_link(social_app):
18
23
  """Click social login link."""
19
24
  res = social_app.get('/login/facebook?scope=email%2Coffline_access', status=302)
20
- assert (res.headers['Location'].startswith(
21
- 'https://www.facebook.com/dialog/oauth/?scope=email%2Coffline_access&state='))
25
+ redirect = urlparse(res.headers['Location'])
26
+ query = parse_qs(redirect.query)
27
+ assert redirect.netloc == 'www.facebook.com', "We should redirect user to facebook"
28
+ assert redirect.path == '/dialog/oauth/', "Path should be oauth"
29
+ assert 'redirect_uri' in query
30
+ assert 'scope' in query
31
+ assert query['redirect_uri'] == ['http://localhost/login/facebook/callback']
32
+ assert query['scope'] == ['email,offline_access']
22
33
 
23
34
 
24
35
  def test_social_login_register(social_config, db_session):
25
36
  """Register fresh user and logs him in."""
26
37
  profile = {
27
- 'accounts': [{'domain': u'facebook.com', 'userid': u'2343'}],
28
- 'displayName': u'teddy',
29
- 'verifiedEmail': u'we@po.pl',
30
- 'preferredUsername': u'teddy',
31
- 'emails': [{'value': u'aasd@bwwqwe.pl'}],
32
- 'name': u'ted'
38
+ 'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
39
+ 'displayName': text_type('teddy'),
40
+ 'verifiedEmail': text_type('we@po.pl'),
41
+ 'preferredUsername': text_type('teddy'),
42
+ 'emails': [{'value': text_type('aasd@bwwqwe.pl')}],
43
+ 'name': text_type('ted')
33
44
  }
34
45
  credentials = {'oauthAccessToken': '7897048593434'}
35
- provider_name = u'facebook'
36
- provider_type = u'facebook'
46
+ provider_name = text_type('facebook')
47
+ provider_type = text_type('facebook')
37
48
  request = testing.DummyRequest()
38
49
  request.user = None
39
50
  request.registry = social_config.registry
40
- request.remote_addr = u'127.0.0.123'
51
+ request.remote_addr = text_type('127.0.0.123')
41
52
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
42
53
 
43
54
  request.login_perform = MagicMock(name='login_perform')
@@ -62,22 +73,22 @@ def test_login_different_social_account(social_config, db_session, facebook_user
62
73
  # profile mock response
63
74
  profile = {
64
75
  # facebook user id is different than user's
65
- 'accounts': [{'domain': u'facebook.com', 'userid': u'2343'}],
66
- 'displayName': u'teddy',
76
+ 'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
77
+ 'displayName': text_type('teddy'),
67
78
  'verifiedEmail': facebook_user.email,
68
- 'preferredUsername': u'teddy',
69
- 'emails': [{'value': u'aasd@bwwqwe.pl'}],
70
- 'name': u'ted'
79
+ 'preferredUsername': text_type('teddy'),
80
+ 'emails': [{'value': text_type('aasd@bwwqwe.pl')}],
81
+ 'name': text_type('ted')
71
82
  }
72
83
  request = testing.DummyRequest()
73
84
  request.user = None
74
85
  request.registry = social_config.registry
75
- request.remote_addr = u'127.0.0.123'
86
+ request.remote_addr = text_type('127.0.0.123')
76
87
  request.context = AuthenticationComplete(
77
88
  profile,
78
89
  {'oauthAccessToken': '7897048593434'},
79
- u'facebook',
80
- u'facebook')
90
+ text_type('facebook'),
91
+ text_type('facebook'))
81
92
 
82
93
  request.login_perform = MagicMock(name='login_perform')
83
94
  request.login_perform.return_value = {'status': True}
@@ -93,20 +104,20 @@ def test_login_social_connect(social_config, active_user, db_session):
93
104
  user = db_session.merge(active_user)
94
105
 
95
106
  profile = {
96
- 'accounts': [{'domain': u'facebook.com', 'userid': u'2343'}],
97
- 'displayName': u'teddy',
98
- 'preferredUsername': u'teddy',
107
+ 'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
108
+ 'displayName': text_type('teddy'),
109
+ 'preferredUsername': text_type('teddy'),
99
110
  'emails': [{'value': user.email}],
100
- 'name': u'ted'
111
+ 'name': text_type('ted')
101
112
  }
102
113
  credentials = {'oauthAccessToken': '7897048593434'}
103
- provider_name = u'facebook'
104
- provider_type = u'facebook'
114
+ provider_name = text_type('facebook')
115
+ provider_type = text_type('facebook')
105
116
  user = None
106
117
  request = testing.DummyRequest()
107
118
  request.user = user
108
119
  request.registry = social_config.registry
109
- request.remote_addr = u'127.0.0.123'
120
+ request.remote_addr = text_type('127.0.0.123')
110
121
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
111
122
 
112
123
  request.login_perform = MagicMock(name='login_perform')
@@ -121,21 +132,21 @@ def test_logged_social_connect_account(social_config, active_user, db_session):
121
132
  user = db_session.merge(active_user)
122
133
 
123
134
  profile = {
124
- 'accounts': [{'domain': u'facebook.com', 'userid': u'2343'}],
125
- 'displayName': u'teddy',
126
- 'preferredUsername': u'teddy',
127
- 'emails': [{'value': u'aasd@basd.pl'}],
128
- 'name': u'ted'
135
+ 'accounts': [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
136
+ 'displayName': text_type('teddy'),
137
+ 'preferredUsername': text_type('teddy'),
138
+ 'emails': [{'value': text_type('aasd@basd.pl')}],
139
+ 'name': text_type('ted')
129
140
  }
130
141
  credentials = {'oauthAccessToken': '7897048593434'}
131
- provider_name = u'facebook'
132
- provider_type = u'facebook'
142
+ provider_name = text_type('facebook')
143
+ provider_type = text_type('facebook')
133
144
  request = testing.DummyRequest()
134
145
  request.user = user
135
146
  request.registry = social_config.registry
136
- request.remote_addr = u'127.0.0.123'
147
+ request.remote_addr = text_type('127.0.0.123')
137
148
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
138
- request._ = lambda msg, *args, **kwargs: msg
149
+ request._ = mock_translate
139
150
 
140
151
  request.login_perform = MagicMock(name='login_perform')
141
152
  request.login_perform.return_value = {'status': True}
@@ -153,21 +164,26 @@ def test_logged_social_connect_self(social_config, facebook_user, db_session):
153
164
  user = db_session.merge(facebook_user)
154
165
 
155
166
  profile = {
156
- 'accounts': [{'domain': u'facebook.com', 'userid': user.provider_id('facebook')}],
157
- 'displayName': u'teddy',
158
- 'preferredUsername': u'teddy',
159
- 'emails': [{'value': user.email}],
160
- 'name': u'ted'
167
+ 'accounts': [{'domain': text_type('facebook.com'), 'userid': user.provider_id('facebook')}],
168
+ 'displayName':
169
+ text_type('teddy'),
170
+ 'preferredUsername':
171
+ text_type('teddy'),
172
+ 'emails':
173
+ [{'value': user.email}],
174
+ 'name':
175
+ text_type('ted')
161
176
  }
162
- credentials = {'oauthAccessToken': '7897048593434'}
163
- provider_name = u'facebook'
164
- provider_type = u'facebook'
177
+ credentials = {'oauthAccessToken':
178
+ '7897048593434'}
179
+ provider_name = text_type('facebook')
180
+ provider_type = text_type('facebook')
165
181
  request = testing.DummyRequest()
166
182
  request.user = user
167
183
  request.registry = social_config.registry
168
- request.remote_addr = u'127.0.0.123'
184
+ request.remote_addr = text_type('127.0.0.123')
169
185
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
170
- request._ = lambda msg, *args, **kwargs: msg
186
+ request._ = mock_translate
171
187
 
172
188
  request.login_perform = MagicMock(name='login_perform')
173
189
  request.login_perform.return_value = {'status': True}
@@ -185,21 +201,27 @@ def test_logged_social_connect_second_account(social_config, facebook_user, db_s
185
201
 
186
202
  # mock request
187
203
  profile = {
188
- 'accounts': [{'domain': u'facebook.com', 'userid': u'2343'}],
189
- 'displayName': u'teddy',
190
- 'preferredUsername': u'teddy',
191
- 'emails': [{'value': u'aasd@basd.pl'}],
192
- 'name': u'ted'
204
+ 'accounts':
205
+ [{'domain': text_type('facebook.com'), 'userid': text_type('2343')}],
206
+ 'displayName':
207
+ text_type('teddy'),
208
+ 'preferredUsername':
209
+ text_type('teddy'),
210
+ 'emails':
211
+ [{'value': text_type('aasd@basd.pl')}],
212
+ 'name':
213
+ text_type('ted')
193
214
  }
194
- credentials = {'oauthAccessToken': '7897048593434'}
195
- provider_name = u'facebook'
196
- provider_type = u'facebook'
215
+ credentials = {'oauthAccessToken':
216
+ '7897048593434'}
217
+ provider_name = text_type('facebook')
218
+ provider_type = text_type('facebook')
197
219
  request = testing.DummyRequest()
198
220
  request.user = user
199
221
  request.registry = social_config.registry
200
- request.remote_addr = u'127.0.0.123'
222
+ request.remote_addr = text_type('127.0.0.123')
201
223
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
202
- request._ = lambda msg, *args, **kwargs: msg
224
+ request._ = mock_translate
203
225
 
204
226
  request.login_perform = MagicMock(name='login_perform')
205
227
  request.login_perform.return_value = {'status': True}
@@ -215,9 +237,10 @@ def test_logged_social_connect_used_account(social_config, facebook_user, db_ses
215
237
  """Try to connect facebook account to logged in user used by other user."""
216
238
  # this user will be logged and trying to connect facebook's user account.
217
239
  fresh_user = User(
218
- email='new@user.pl',
219
- password='somepassword',
220
- address_ip='127.0.0.1')
240
+ email=text_type('new@user.pl'),
241
+ password=text_type('somepassword'),
242
+ address_ip=text_type('127.0.0.1')
243
+ )
221
244
  db_session.add(fresh_user)
222
245
  transaction.commit()
223
246
  user = db_session.merge(facebook_user)
@@ -225,21 +248,26 @@ def test_logged_social_connect_used_account(social_config, facebook_user, db_ses
225
248
 
226
249
  # mock request
227
250
  profile = {
228
- 'accounts': [{'domain': u'facebook.com', 'userid': user.provider_id('facebook')}],
229
- 'displayName': u'teddy',
230
- 'preferredUsername': u'teddy',
231
- 'emails': [{'value': u'aasd@basd.pl'}],
232
- 'name': u'ted'
251
+ 'accounts':
252
+ [{'domain': text_type('facebook.com'), 'userid': user.provider_id('facebook')}],
253
+ 'displayName':
254
+ text_type('teddy'),
255
+ 'preferredUsername':
256
+ text_type('teddy'),
257
+ 'emails':
258
+ [{'value': text_type('aasd@basd.pl')}],
259
+ 'name':
260
+ text_type('ted')
233
261
  }
234
262
  credentials = {'oauthAccessToken': '7897048593434'}
235
- provider_name = u'facebook'
236
- provider_type = u'facebook'
263
+ provider_name = text_type('facebook')
264
+ provider_type = text_type('facebook')
237
265
  request = testing.DummyRequest()
238
266
  request.user = fresh_user
239
267
  request.registry = social_config.registry
240
- request.remote_addr = u'127.0.0.123'
268
+ request.remote_addr = text_type('127.0.0.123')
241
269
  request.context = AuthenticationComplete(profile, credentials, provider_name, provider_type)
242
- request._ = lambda msg, *args, **kwargs: msg
270
+ request._ = mock_translate
243
271
 
244
272
  request.login_perform = MagicMock(name='login_perform')
245
273
  request.login_perform.return_value = {'status': True}
Binary file
Binary file
@@ -1,8 +1,12 @@
1
1
  """Registration related tests."""
2
- from HTMLParser import HTMLParser
2
+ try:
3
+ from HTMLParser import HTMLParser
4
+ except ImportError:
5
+ from html.parser import HTMLParser
3
6
 
4
7
  import pytest
5
8
  import transaction
9
+ from pyramid.compat import text_type
6
10
  from sqlalchemy.orm.exc import NoResultFound
7
11
 
8
12
  from pyramid_fullauth.models import User
@@ -48,7 +52,7 @@ def test_register_user_exists(db_session, user, default_app):
48
52
  res = res.form.submit(extra_environ={'REMOTE_ADDR': '0.0.0.0'})
49
53
  transaction.commit()
50
54
 
51
- assert 'User with given e-mail already exists' in res.body
55
+ assert 'User with given e-mail already exists' in res.body.decode('unicode_escape')
52
56
 
53
57
 
54
58
  @pytest.mark.parametrize('email, password, confirm_password, error', (
@@ -62,7 +66,7 @@ def test_register_user_exists(db_session, user, default_app):
62
66
  (DEFAULT_USER['email'], DEFAULT_USER['password'], DEFAULT_USER['password'] + 'Typo',
63
67
  'Passwords don\'t match'),
64
68
  # long, incorect email
65
- (u'email' * 100 + '@wap.pl', DEFAULT_USER['password'], DEFAULT_USER['password'],
69
+ (text_type('email') * 100 + text_type('@wap.pl'), DEFAULT_USER['password'], DEFAULT_USER['password'],
66
70
  'Incorrect e-mail format'),
67
71
  # too short password
68
72
  (DEFAULT_USER['email'], '12', '12',
@@ -82,7 +86,7 @@ def test_register_error(db_session, default_app, email, password, confirm_passwo
82
86
  res = res.form.submit(extra_environ={'REMOTE_ADDR': '0.0.0.0'})
83
87
  transaction.commit()
84
88
 
85
- assert error in HTMLParser().unescape(res.body)
89
+ assert error in HTMLParser().unescape(res.body.decode('unicode_escape'))
86
90
  assert db_session.query(User).count() == 0
87
91
 
88
92
 
@@ -111,7 +115,7 @@ def test_no_pass_confirm(db_session, nopassconfirm_app):
111
115
  res.form['password'] = DEFAULT_USER['password']
112
116
  res = res.form.submit(extra_environ={'REMOTE_ADDR': '0.0.0.0'})
113
117
 
114
- assert 'Passwords don\'t match!' not in HTMLParser().unescape(res.body)
118
+ assert 'Passwords don\'t match!' not in HTMLParser().unescape(res.body.decode('unicode_escape'))
115
119
  transaction.commit()
116
120
 
117
121
  user = db_session.query(User).filter(User.email == DEFAULT_USER['email']).one()
Binary file
tests/views/test_reset.py CHANGED
@@ -1,6 +1,11 @@
1
1
  """Reset password views."""
2
- from HTMLParser import HTMLParser
2
+ try:
3
+ from HTMLParser import HTMLParser
4
+ except ImportError:
5
+ from html.parser import HTMLParser
6
+
3
7
  import transaction
8
+ from pyramid.compat import text_type
4
9
 
5
10
  from pyramid_fullauth.models import User
6
11
 
@@ -33,9 +38,9 @@ def test_reset_email_not_exists(user, db_session, default_app):
33
38
  user = db_session.merge(user)
34
39
 
35
40
  res = default_app.get('/password/reset')
36
- res.form['email'] = u'wrong@example.com'
41
+ res.form['email'] = text_type('wrong@example.com')
37
42
  res = res.form.submit()
38
- assert 'Error! User does not exists' in res
43
+ assert 'Error! User does not exist' in res
39
44
 
40
45
 
41
46
  def test_reset_proceed(user, db_session, default_app):
@@ -82,7 +87,7 @@ def test_reset_proceed_wrong_confirm(user, db_session, default_app):
82
87
  res.form['confirm_password'] = NEW_PASSWORD + 'Typo'
83
88
  res = res.form.submit()
84
89
 
85
- assert 'Error! Password doesn\'t match' in HTMLParser().unescape(res.body)
90
+ assert 'Error! Password doesn\'t match' in HTMLParser().unescape(res.body.decode('unicode_escape'))
86
91
 
87
92
 
88
93
  def test_reset_proceed_wrong_csrf(user, db_session, default_app):
Binary file