Skip to content

Commit

Permalink
更新至 3.21.8 版本
Browse files Browse the repository at this point in the history
  • Loading branch information
redabc committed Sep 6, 2021
1 parent 076ff33 commit c3447b8
Show file tree
Hide file tree
Showing 27 changed files with 2,482 additions and 809 deletions.
362 changes: 185 additions & 177 deletions README.md

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion README_CN.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
Version 3.21.4
Version 3.21.8

新特性:

1. 新增客户端加密特性。

-------------------------------------------------------------------------------------------------

Version 3.21.4

新特性:

Expand Down
83 changes: 83 additions & 0 deletions examples/crypto_client_sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
# Copyright 2019 Huawei Technologies Co.,Ltd.
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use
# this file except in compliance with the License. You may obtain a copy of the
# License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software distributed
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.

"""
This sample demonstrates how to using crypto client in OBS Python SDK.
"""
from obs import CompleteMultipartUploadRequest, CompletePart, CryptoObsClient
from obs.obs_cipher_suite import CTRCipherGenerator, CtrRSACipherGenerator

AK = '*** Provide your Access Key ***'
SK = '*** Provide your Secret Key ***'
server = 'https://your-endpoint'

bucketName = 'my-obs-bucket-demo'
test_file = "path/to/your/test/file"

# Construct a crypto obs client with CtrRSACipherGenerator
# CtrRSACipherGenerator using public key
public_g = CtrRSACipherGenerator("/path/to/public_key.pem", master_key_info="Test_Key22")
public_client = CryptoObsClient(access_key_id=AK, secret_access_key=SK, server=server, cipher_generator=public_g)

# CtrRSACipherGenerator using private key
private_g = CtrRSACipherGenerator("/path/to/private_key.pem", master_key_info="Test_Key22")
private_client = CryptoObsClient(access_key_id=AK, secret_access_key=SK, server=server, cipher_generator=private_g)

# Construct a crypto obs client with CTRCipherGenerator
# The byte length of master key mast equal 32
ctr_g = CTRCipherGenerator("your-master-key")
ctr_client = CryptoObsClient(access_key_id=AK, secret_access_key=SK, server=server, cipher_generator=ctr_g)

# Create bucket
bucketClient = ctr_client.bucketClient(bucketName)

# Upload file
# Uploading file in crypto obsClient is same as in normal obsClient
upload_object_key = "upload_test_file_with_ctr_client"
ctr_client_result = ctr_client.putFile(bucketName, upload_object_key, test_file)
if ctr_client_result.status < 300:
print('Upload finished\n')

# Multipart upload File

object_key = "Multipart_upload_File"

# Step 1: Generate a cipher using empty string
print('Step 1: Generate a cipher using empty string \n')
cipher = ctr_client.cipher_generator.new("")

# Step 2: initiate multipart upload
print('Step 2: initiate multipart upload \n')
init_result = ctr_client.initiateEncryptedMultipartUpload(bucketName, object_key, cipher)
uploadId = init_result.body.uploadId

# Step 3: upload a part
print('Step 3: upload a part\n')
partNum = 1
resp = ctr_client.uploadEncryptedPart(bucketName, object_key, partNumber=partNum, uploadId=uploadId,
crypto_cipher=cipher, content='Hello OBS')
etag = dict(resp.header).get('etag')

# Step 4: complete multipart upload
print('Step 4: complete multipart upload\n')
resp = ctr_client.completeMultipartUpload(bucketName, object_key, uploadId,
CompleteMultipartUploadRequest([CompletePart(partNum=partNum, etag=etag)]))
if resp.status < 300:
print('Complete finished\n')

# Download file
# Downloading file in crypto obsClient is same as in normal obsClient
download_result = ctr_client.getObject(bucketName, upload_object_key, downloadPath="/path/to/save")
if download_result.status < 300:
print('Download finished\n')
8 changes: 7 additions & 1 deletion src/obs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
from obs.model import ListMultipartUploadsRequest, GetObjectRequest, UploadFileHeader, Payer
from obs.model import ExtensionHeader, FetchStatus
from obs.workflow import WorkflowClient
from obs.crypto_client import CryptoObsClient
from obs.obs_cipher_suite import CTRCipherGenerator
from obs.obs_cipher_suite import CtrRSACipherGenerator

__all__ = [
'LogConf',
Expand Down Expand Up @@ -85,5 +88,8 @@
'Payer',
'ExtensionHeader',
'FetchStatus',
'WorkflowClient'
'WorkflowClient',
'CryptoObsClient',
'CTRCipherGenerator',
'CtrRSACipherGenerator'
]
43 changes: 25 additions & 18 deletions src/obs/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def doAuth(self, method, bucket, key, path_args, headers, expires=None):
}

def getSignature(self, method, bucket, key, path_args, headers, expires=None):
canonical_string = self.__make_canonicalstring(method, bucket, key, path_args, headers, expires)
canonical_string = self.__make_canonical_string(method, bucket, key, path_args, headers, expires)
return {
'Signature': self.hmacSha128(canonical_string),
const.CANONICAL_STRING: canonical_string
Expand All @@ -53,10 +53,10 @@ def hmacSha128(self, canonical_string):

return encode_canonical

def __make_canonicalstring(self, method, bucket_name, key, path_args, headers, expires=None):
def __make_canonical_string(self, method, bucket_name, key, path_args, headers, expires=None):
interesting_headers = self.__make_canonicalstring_interesting_headers(headers, expires)
keylist = sorted(interesting_headers.keys())
str_list = self.__make_canonicalstring_str_list(keylist, method, interesting_headers)
key_list = sorted(interesting_headers.keys())
str_list = self.__make_canonicalstring_str_list(key_list, method, interesting_headers)
URI = ''
_bucket_name = self.server if self.is_cname else bucket_name
if _bucket_name:
Expand Down Expand Up @@ -100,18 +100,18 @@ def __make_canonicalstring_interesting_headers(self, headers, expires):
s = headers.get(hash_key)
interesting_headers[lk] = ''.join(s)

keylist = interesting_headers.keys()
key_list = interesting_headers.keys()

if self.ha.date_header() in keylist:
if self.ha.date_header() in key_list:
interesting_headers[const.DATE_HEADER.lower()] = ''

if expires:
interesting_headers[const.DATE_HEADER.lower()] = expires

if const.CONTENT_TYPE_HEADER.lower() not in keylist:
if const.CONTENT_TYPE_HEADER.lower() not in key_list:
interesting_headers[const.CONTENT_TYPE_HEADER.lower()] = ''

if const.CONTENT_MD5_HEADER.lower() not in keylist:
if const.CONTENT_MD5_HEADER.lower() not in key_list:
interesting_headers[const.CONTENT_MD5_HEADER.lower()] = ''

return interesting_headers
Expand Down Expand Up @@ -148,24 +148,25 @@ def doAuth(self, method, bucket, key, args_path, headers):
headers = headers if isinstance(headers, dict) else {}
headers[self.ha.content_sha256_header()] = self.CONTENT_SHA256

credenttial = self.getCredenttial()
credential = self.getCredential()
headMap = self.setMapKeyLower(headers)
signedHeaders = self.getSignedHeaders(headMap)
ret = self.getSignature(method, bucket, key, args_path, headMap, signedHeaders)
auth = 'AWS4-HMAC-SHA256 Credential=%s,SignedHeaders=%s,Signature=%s' % (
credenttial, signedHeaders, ret['Signature'])
credential, signedHeaders, ret['Signature'])
return {
const.AUTHORIZATION_HEADER: auth,
const.CANONICAL_REQUEST: ret[const.CANONICAL_REQUEST]
}

def getCredenttial(self):
def getCredential(self):
return '%s/%s/%s/s3/aws4_request' % (self.ak, self.shortDate, self.region)

def getScope(self):
return '%s/%s/s3/aws4_request' % (self.shortDate, self.region)

def getSignedHeaders(self, headMap):
@staticmethod
def getSignedHeaders(headMap):
headList = sorted(headMap.items(), key=lambda d: d[0])
signedHeaders = ''
i = 0
Expand Down Expand Up @@ -194,7 +195,8 @@ def getSignature(self, method, bucket, key, args_path, headMap, signedHeaders, p
const.CANONICAL_REQUEST: cannonicalRequest
}

def hmacSha256(self, signingKey, stringToSign):
@staticmethod
def hmacSha256(signingKey, stringToSign):
return hmac.new(signingKey, stringToSign, hashlib.sha256).hexdigest()

def getSigningKey_python2(self):
Expand Down Expand Up @@ -222,10 +224,12 @@ def getCanonicalRequest(self, method, bucket, key, args_path, headMap, signedHea
output.append(self.CONTENT_SHA256 if payload is None else payload)
return '\n'.join(output)

def __shaCannonicalRequest_python2(self, cannonicalRequest):
@staticmethod
def __shaCannonicalRequest_python2(cannonicalRequest):
return hashlib.sha256(cannonicalRequest).hexdigest()

def __shaCannonicalRequest_python3(self, cannonicalRequest):
@staticmethod
def __shaCannonicalRequest_python3(cannonicalRequest):
return hashlib.sha256(cannonicalRequest.encode('UTF-8')).hexdigest()

def getCanonicalURI(self, bucket=None, key=None):
Expand All @@ -238,7 +242,8 @@ def getCanonicalURI(self, bucket=None, key=None):
URI = '/'
return util.encode_object_key(URI)

def getCanonicalQueryString(self, args_path):
@staticmethod
def getCanonicalQueryString(args_path):
canonMap = {}
for key, value in args_path.items():
canonMap[key] = value
Expand All @@ -252,7 +257,8 @@ def getCanonicalQueryString(self, args_path):
i = 1
return queryStr

def getCanonicalHeaders(self, headMap):
@staticmethod
def getCanonicalHeaders(headMap):
headList = sorted(headMap.items(), key=lambda d: d[0])
canonicalHeaderStr = ''
for val in headList:
Expand All @@ -264,7 +270,8 @@ def getCanonicalHeaders(self, headMap):
canonicalHeaderStr += val[0] + ':' + str(val[1]) + '\n'
return canonicalHeaderStr

def setMapKeyLower(self, inputMap):
@staticmethod
def setMapKeyLower(inputMap):
outputMap = {}
for key in inputMap.keys():
outputMap[key.lower()] = inputMap[key]
Expand Down
6 changes: 3 additions & 3 deletions src/obs/bucket.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ def __init__(self, obsClient, bucketName):

def __getattr__(self, key):
if key in self.allowedMethod and hasattr(self.__obsClient, key):
orignalMethod = getattr(self.__obsClient, key)
if callable(orignalMethod):
original_method = getattr(self.__obsClient, key)
if callable(original_method):
def delegate(*args, **kwargs):
_args = list(args)
if key == 'copyObject':
Expand All @@ -104,7 +104,7 @@ def delegate(*args, **kwargs):
else:
if 'bucketName' not in kwargs:
_args.insert(0, self.__bucketName)
return orignalMethod(*_args, **kwargs)
return original_method(*_args, **kwargs)

return delegate
return super(BucketClient, self).__getattribute__(key)
Loading

0 comments on commit c3447b8

Please sign in to comment.