1- from copy import deepcopy
2- import ssl
3- import sys
4- import time
5-
61from flask import current_app
7- from boto .auth_handler import AuthHandler
8- import boto .auth
9-
10- from boto .exception import S3ResponseError
11- from boto .s3 .key import Key
12- from boto .s3 .bucket import Bucket
13- from boto .s3 .connection import S3Connection , OrdinaryCallingFormat
14- from boto .provider import Provider
15- import jwt
2+ from botocore .config import Config
3+ import boto3
164from werkzeug .exceptions import BadRequest
175from boto3 .session import Session
186from botocore .client import Config
197from pybossa .cloud_store_api .base_conn import BaseConnection
208from os import environ
219
10+ from pybossa .cloud_store_api .proxied_s3_client import ProxiedS3Client
11+ from pybossa .cloud_store_api .s3_client_wrapper import S3ClientWrapper
12+
2213
2314def check_store (store ):
2415 if not store :
@@ -60,59 +51,13 @@ def create_connection(**kwargs):
6051 proxy_url = kwargs .get ("proxy_url" )
6152 )
6253 if 'object_service' in kwargs :
63- current_app .logger .info ("Calling ProxiedConnection " )
64- conn = ProxiedConnection (** kwargs )
54+ current_app .logger .info ("Calling ProxiedS3Client " )
55+ conn = ProxiedS3Client (** kwargs )
6556 else :
66- current_app .logger .info ("Calling CustomConnection " )
67- conn = CustomConnection (** kwargs )
57+ current_app .logger .info ("Calling S3ClientWrapper " )
58+ conn = S3ClientWrapper (** kwargs )
6859 return conn
6960
70-
71- class CustomProvider (Provider ):
72- """Extend Provider to carry information about the end service provider, in
73- case the service is being proxied.
74- """
75-
76- def __init__ (self , name , access_key = None , secret_key = None ,
77- security_token = None , profile_name = None , object_service = None ,
78- auth_headers = None ):
79- self .object_service = object_service or name
80- self .auth_headers = auth_headers
81- super (CustomProvider , self ).__init__ (name , access_key , secret_key ,
82- security_token , profile_name )
83-
84-
85- class CustomConnection (S3Connection ):
86-
87- def __init__ (self , * args , ** kwargs ):
88- if not kwargs .get ('calling_format' ):
89- kwargs ['calling_format' ] = OrdinaryCallingFormat ()
90-
91- kwargs ['provider' ] = CustomProvider ('aws' ,
92- kwargs .get ('aws_access_key_id' ),
93- kwargs .get ('aws_secret_access_key' ),
94- kwargs .get ('security_token' ),
95- kwargs .get ('profile_name' ),
96- kwargs .pop ('object_service' , None ),
97- kwargs .pop ('auth_headers' , None ))
98-
99- kwargs ['bucket_class' ] = CustomBucket
100-
101- ssl_no_verify = kwargs .pop ('s3_ssl_no_verify' , False )
102- self .host_suffix = kwargs .pop ('host_suffix' , '' )
103-
104- super (CustomConnection , self ).__init__ (* args , ** kwargs )
105-
106- if kwargs .get ('is_secure' , True ) and ssl_no_verify :
107- self .https_validate_certificates = False
108- context = ssl ._create_unverified_context ()
109- self .http_connection_kwargs ['context' ] = context
110-
111- def get_path (self , path = '/' , * args , ** kwargs ):
112- ret = super (CustomConnection , self ).get_path (path , * args , ** kwargs )
113- return self .host_suffix + ret
114-
115-
11661class CustomConnectionV2 (BaseConnection ):
11762 def __init__ (
11863 self ,
@@ -133,89 +78,3 @@ def __init__(
13378 proxies = {"https" : proxy_url , "http" : proxy_url },
13479 ),
13580 )
136-
137-
138- class CustomBucket (Bucket ):
139- """Handle both 200 and 204 as response code"""
140-
141- def delete_key (self , * args , ** kwargs ):
142- try :
143- super (CustomBucket , self ).delete_key (* args , ** kwargs )
144- except S3ResponseError as e :
145- if e .status != 200 :
146- raise
147-
148-
149- class ProxiedKey (Key ):
150-
151- def should_retry (self , response , chunked_transfer = False ):
152- if 200 <= response .status <= 299 :
153- return True
154- return super (ProxiedKey , self ).should_retry (response , chunked_transfer )
155-
156-
157- class ProxiedBucket (CustomBucket ):
158-
159- def __init__ (self , * args , ** kwargs ):
160- super (ProxiedBucket , self ).__init__ (* args , ** kwargs )
161- self .set_key_class (ProxiedKey )
162-
163-
164- class ProxiedConnection (CustomConnection ):
165- """Object Store connection through proxy API. Sets the proper headers and
166- creates the jwt; use the appropriate Bucket and Key classes.
167- """
168-
169- def __init__ (self , client_id , client_secret , object_service , * args , ** kwargs ):
170- self .client_id = client_id
171- self .client_secret = client_secret
172- kwargs ['object_service' ] = object_service
173- super (ProxiedConnection , self ).__init__ (* args , ** kwargs )
174- self .set_bucket_class (ProxiedBucket )
175-
176- def make_request (self , method , bucket = '' , key = '' , headers = None , data = '' ,
177- query_args = None , sender = None , override_num_retries = None ,
178- retry_handler = None ):
179- headers = headers or {}
180- headers ['jwt' ] = self .create_jwt (method , self .host , bucket , key )
181- headers ['x-objectservice-id' ] = self .provider .object_service .upper ()
182- current_app .logger .info ("Calling ProxiedConnection.make_request. headers %s" , str (headers ))
183- return super (ProxiedConnection , self ).make_request (method , bucket , key ,
184- headers , data , query_args , sender , override_num_retries ,
185- retry_handler )
186-
187- def create_jwt (self , method , host , bucket , key ):
188- now = int (time .time ())
189- path = self .get_path (self .calling_format .build_path_base (bucket , key ))
190- current_app .logger .info ("create_jwt called. method %s, host %s, bucket %s, key %s, path %s" , method , host , str (bucket ), str (key ), str (path ))
191- payload = {
192- 'iat' : now ,
193- 'nbf' : now ,
194- 'exp' : now + 300 ,
195- 'method' : method ,
196- 'iss' : self .client_id ,
197- 'host' : host ,
198- 'path' : path ,
199- 'region' : 'ny'
200- }
201- return jwt .encode (payload , self .client_secret , algorithm = 'HS256' )
202-
203-
204- class CustomAuthHandler (AuthHandler ):
205- """Implements sending of custom auth headers"""
206-
207- capability = ['s3' ]
208-
209- def __init__ (self , host , config , provider ):
210- if not provider .auth_headers :
211- raise boto .auth_handler .NotReadyToAuthenticate ()
212- self ._provider = provider
213- super (CustomAuthHandler , self ).__init__ (host , config , provider )
214-
215- def add_auth (self , http_request , ** kwargs ):
216- headers = http_request .headers
217- for header , attr in self ._provider .auth_headers :
218- headers [header ] = getattr (self ._provider , attr )
219-
220- def sign_string (self , * args , ** kwargs ):
221- return ''
0 commit comments