1616 from StringIO import StringIO as BytesIO
1717
1818from dropbox import (
19+ create_session ,
1920 Dropbox ,
2021 DropboxOAuth2Flow ,
2122 DropboxTeam ,
3940 PathRoot ,
4041 PathRoot_validator ,
4142)
43+ from dropbox .session import SSLError
4244
4345# Key Types
4446REFRESH_TOKEN_KEY = "REFRESH_TOKEN"
@@ -65,34 +67,43 @@ def _value_from_env_or_die(env_name):
6567 sys .exit (1 )
6668 return value
6769
70+ _TRUSTED_CERTS_FILE = os .path .join (os .path .dirname (__file__ ), "trusted-certs.crt" )
71+ _EXPIRED_CERTS_FILE = os .path .join (os .path .dirname (__file__ ), "expired-certs.crt" )
72+
73+ # enables testing both with and without a manually-provided CA bundle
74+ @pytest .fixture (params = [None , _TRUSTED_CERTS_FILE ], ids = ["no-pinning" , "pinning" ])
75+ def dbx_session (request ):
76+ return create_session (ca_certs = request .param )
77+
6878
6979@pytest .fixture ()
70- def dbx_from_env ():
80+ def dbx_from_env (dbx_session ):
7181 oauth2_token = _value_from_env_or_die (format_env_name ())
72- return Dropbox (oauth2_token )
82+ return Dropbox (oauth2_token , session = dbx_session )
7383
7484
7585@pytest .fixture ()
76- def refresh_dbx_from_env ():
86+ def refresh_dbx_from_env (dbx_session ):
7787 refresh_token = _value_from_env_or_die (format_env_name (SCOPED_KEY , USER_KEY , REFRESH_TOKEN_KEY ))
7888 app_key = _value_from_env_or_die (format_env_name (SCOPED_KEY , USER_KEY , CLIENT_ID_KEY ))
7989 app_secret = _value_from_env_or_die (format_env_name (SCOPED_KEY , USER_KEY , CLIENT_SECRET_KEY ))
8090 return Dropbox (oauth2_refresh_token = refresh_token ,
81- app_key = app_key , app_secret = app_secret )
91+ app_key = app_key , app_secret = app_secret ,
92+ session = dbx_session )
8293
8394
8495@pytest .fixture ()
85- def dbx_team_from_env ():
96+ def dbx_team_from_env (dbx_session ):
8697 team_oauth2_token = _value_from_env_or_die (
8798 format_env_name (SCOPED_KEY , TEAM_KEY , ACCESS_TOKEN_KEY ))
88- return DropboxTeam (team_oauth2_token )
99+ return DropboxTeam (team_oauth2_token , session = dbx_session )
89100
90101
91102@pytest .fixture ()
92- def dbx_app_auth_from_env ():
103+ def dbx_app_auth_from_env (dbx_session ):
93104 app_key = _value_from_env_or_die (format_env_name (SCOPED_KEY , USER_KEY , CLIENT_ID_KEY ))
94105 app_secret = _value_from_env_or_die (format_env_name (SCOPED_KEY , USER_KEY , CLIENT_SECRET_KEY ))
95- return Dropbox (app_key = app_key , app_secret = app_secret )
106+ return Dropbox (app_key = app_key , app_secret = app_secret , session = dbx_session )
96107
97108
98109@pytest .fixture ()
@@ -110,7 +121,7 @@ def dbx_share_url_from_env():
110121TIMESTAMP = str (datetime .datetime .utcnow ())
111122STATIC_FILE = "/test.txt"
112123
113- @pytest .fixture (scope = 'module' , autouse = True )
124+ @pytest .fixture (scope = 'module' )
114125def pytest_setup ():
115126 print ("Setup" )
116127 dbx = Dropbox (_value_from_env_or_die (format_env_name ()))
@@ -125,47 +136,14 @@ def pytest_setup():
125136 except Exception :
126137 print ("File not found" )
127138
128-
129139@pytest .mark .usefixtures (
140+ "pytest_setup" ,
130141 "dbx_from_env" ,
131142 "refresh_dbx_from_env" ,
132143 "dbx_app_auth_from_env" ,
133- "dbx_share_url_from_env"
144+ "dbx_share_url_from_env" ,
134145)
135146class TestDropbox :
136- def test_default_oauth2_urls (self ):
137- flow_obj = DropboxOAuth2Flow ('dummy_app_key' , 'dummy_app_secret' ,
138- 'http://localhost/dummy' , 'dummy_session' , 'dbx-auth-csrf-token' )
139-
140- assert re .match (
141- r'^https://{}/oauth2/authorize\?' .format (re .escape (session .WEB_HOST )),
142- flow_obj ._get_authorize_url ('http://localhost/redirect' , 'state' , 'legacy' ),
143- )
144-
145- assert flow_obj .build_url (
146- '/oauth2/authorize'
147- ) == 'https://{}/oauth2/authorize' .format (session .API_HOST )
148-
149- assert flow_obj .build_url (
150- '/oauth2/authorize' , host = session .WEB_HOST
151- ) == 'https://{}/oauth2/authorize' .format (session .WEB_HOST )
152-
153- def test_bad_auth (self ):
154- # Test malformed token
155- malformed_token_dbx = Dropbox (MALFORMED_TOKEN )
156- # TODO: backend is no longer returning `BadInputError`
157- # with pytest.raises(BadInputError,) as cm:
158- # malformed_token_dbx.files_list_folder('')
159- # assert 'token is malformed' in cm.value.message
160- with pytest .raises (AuthError ,):
161- malformed_token_dbx .files_list_folder ('' )
162-
163- # Test reasonable-looking invalid token
164- invalid_token_dbx = Dropbox (INVALID_TOKEN )
165- with pytest .raises (AuthError ) as cm :
166- invalid_token_dbx .files_list_folder ('' )
167- assert cm .value .error .is_invalid_access_token ()
168-
169147 def test_multi_auth (self , dbx_from_env , dbx_app_auth_from_env , dbx_share_url_from_env ):
170148 # Test for user (with oauth token)
171149 preview_result , resp = dbx_from_env .files_get_thumbnail_v2 (
@@ -280,7 +258,10 @@ def test_versioned_route(self, dbx_from_env):
280258 # Verify response type is of v2 route
281259 assert isinstance (resp , DeleteResult )
282260
283- @pytest .mark .usefixtures ("dbx_team_from_env" )
261+ @pytest .mark .usefixtures (
262+ "pytest_setup" ,
263+ "dbx_team_from_env" ,
264+ )
284265class TestDropboxTeam :
285266 def test_team (self , dbx_team_from_env ):
286267 dbx_team_from_env .team_groups_list ()
@@ -310,3 +291,48 @@ def test_clone_when_team_linked(self, dbx_team_from_env):
310291 new_dbxt = dbx_team_from_env .clone ()
311292 assert dbx_team_from_env is not new_dbxt
312293 assert isinstance (new_dbxt , dbx_team_from_env .__class__ )
294+
295+ def test_default_oauth2_urls ():
296+ flow_obj = DropboxOAuth2Flow ('dummy_app_key' , 'dummy_app_secret' ,
297+ 'http://localhost/dummy' , 'dummy_session' , 'dbx-auth-csrf-token' )
298+
299+ assert re .match (
300+ r'^https://{}/oauth2/authorize\?' .format (re .escape (session .WEB_HOST )),
301+ flow_obj ._get_authorize_url ('http://localhost/redirect' , 'state' , 'legacy' ),
302+ )
303+
304+ assert flow_obj .build_url (
305+ '/oauth2/authorize'
306+ ) == 'https://{}/oauth2/authorize' .format (session .API_HOST )
307+
308+ assert flow_obj .build_url (
309+ '/oauth2/authorize' , host = session .WEB_HOST
310+ ) == 'https://{}/oauth2/authorize' .format (session .WEB_HOST )
311+
312+ def test_bad_auth (dbx_session ):
313+ # Test malformed token
314+ malformed_token_dbx = Dropbox (MALFORMED_TOKEN , session = dbx_session )
315+ # TODO: backend is no longer returning `BadInputError`
316+ # with pytest.raises(BadInputError,) as cm:
317+ # malformed_token_dbx.files_list_folder('')
318+ # assert 'token is malformed' in cm.value.message
319+ with pytest .raises (AuthError ):
320+ malformed_token_dbx .files_list_folder ('' )
321+
322+ # Test reasonable-looking invalid token
323+ invalid_token_dbx = Dropbox (INVALID_TOKEN , session = dbx_session )
324+ with pytest .raises (AuthError ) as cm :
325+ invalid_token_dbx .files_list_folder ('' )
326+ assert cm .value .error .is_invalid_access_token ()
327+
328+ def test_bad_pins ():
329+ # sanity-check: if we're pinning using expired pins, we should fail w/ an SSL error
330+ _dbx = Dropbox ("dummy_token" , ca_certs = _EXPIRED_CERTS_FILE )
331+ with pytest .raises (SSLError ,):
332+ _dbx .files_list_folder ('' )
333+
334+ def test_bad_pins_session ():
335+ _session = create_session (ca_certs = _EXPIRED_CERTS_FILE )
336+ _dbx = Dropbox ("dummy_token2" , session = _session )
337+ with pytest .raises (SSLError ,):
338+ _dbx .files_list_folder ('' )
0 commit comments