UPD: MacCloud/S3: step-86: The S3 configuration is more reasonably divided into Driver-level, Connection-level, and Account-level

This commit is contained in:
rich2014 2025-05-01 19:27:39 +08:00
commit 27b84a6af6
4 changed files with 99 additions and 47 deletions

View file

@ -106,14 +106,17 @@
<Unit>
<Filename Value="drivers/aws/uawsauth.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uAWSAuth"/>
</Unit>
<Unit>
<Filename Value="drivers/aws/uawscore.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uAWSCore"/>
</Unit>
<Unit>
<Filename Value="drivers/aws/us3client.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uS3Client"/>
</Unit>
</Units>
</ProjectOptions>

View file

@ -18,11 +18,9 @@ type
{ TAWSAuthSessionParams }
TAWSAuthSessionParams = record
config: TAWSConfig;
config: TAWSCredentialConfig;
connectionData: TAWSConnectionData;
resultProcessFunc: TCloudDriverResultProcessFunc;
region: String;
endPoint: String;
defaultBucket: String;
end;
{ TAWSSigner }
@ -30,7 +28,8 @@ type
TAWSSigner = class
strict private
_params: TAWSAuthSessionParams;
_config: TAWSConfig;
_config: TAWSCredentialConfig;
_connectionData: TAWSConnectionData;
_accessKey: TAWSAccessKey;
_request: NSMutableURLRequest;
protected
@ -55,9 +54,7 @@ type
TAWSAuthSession = class( TCloudDriverAuthSession )
strict protected
_params: TAWSAuthSessionParams;
_config: TAWSConfig;
_accessKey: TAWSAccessKey;
_signer: TAWSSigner;
private
procedure addNeededHeader( const request: NSMutableURLRequest );
public
@ -69,6 +66,7 @@ type
public
property params: TAWSAuthSessionParams read _params;
property accessKey: TAWSAccessKey read _accessKey write setAccessKey;
property connectionData: TAWSConnectionData read _params.connectionData write _params.connectionData;
end;
implementation
@ -113,10 +111,10 @@ begin
addHostHeaderIfNeeded;
end;
constructor TAWSAuthSession.Create( const params: TAWSAuthSessionParams );
constructor TAWSAuthSession.Create( const params: TAWSAuthSessionParams );
begin
_params:= params;
_config:= params.config;
_accessKey:= TAWSAccessKey.Create( '', '' );
end;
destructor TAWSAuthSession.Destroy;
@ -129,7 +127,7 @@ var
session: TAWSAuthSession;
begin
session:= TAWSAuthSession.Create( _params );
session.setAccessKey( TAWSCloudDriver(driver).getAccessKey );
session.setAccessKey( _accessKey.clone );
Result:= session;
end;
@ -168,6 +166,7 @@ constructor TAWSSigner.Create(
begin
_params:= params;
_config:= _params.config;
_connectionData:= _params.connectionData;
_accessKey:= accessKey;
_request:= request;
end;
@ -234,17 +233,17 @@ var
dateRegionServiceKey: NSData;
begin
dateString:= buildDateYYYYMMDDString;
keyString:= StringToNSString( _config.credentialPrefix + _accessKey.secret );
keyString:= StringToNSString( _config.prefix + _accessKey.secret );
key:= keyString.dataUsingEncoding( NSUTF8StringEncoding );
dateKey:= THashUtil.HmacSha256( key, dateString );
dateRegionKey:= THashUtil.HmacSha256( dateKey, NSSTR(_params.region) );
dateRegionServiceKey:= THashUtil.HmacSha256( dateRegionKey, NSSTR(_config.credentialService) );
Result:= THashUtil.HmacSha256( dateRegionServiceKey, NSSTR(_config.credentialRequest) );
dateRegionKey:= THashUtil.HmacSha256( dateKey, NSSTR(_connectionData.region) );
dateRegionServiceKey:= THashUtil.HmacSha256( dateRegionKey, NSSTR(_config.service) );
Result:= THashUtil.HmacSha256( dateRegionServiceKey, NSSTR(_config.request) );
end;
function TAWSSigner.buildHmacAlgorithmString: NSString;
begin
Result:= NSSTR( _config.credentialVersionAlgorithm );
Result:= NSSTR( _config.versionAlgorithm );
end;
function TAWSSigner.buildScopeString: NSString;
@ -255,9 +254,9 @@ var
signProduct: NSString;
begin
signDate:= buildDateYYYYMMDDString;
signService:= NSSTR( _config.credentialService );
signRegion:= NSSTR( _params.region );
signProduct:= NSSTR( _config.credentialRequest );
signService:= NSSTR( _config.service );
signRegion:= NSSTR( _connectionData.region );
signProduct:= NSSTR( _config.request );
Result:= NSString.stringWithFormat( NSSTR('%@/%@/%@/%@'),
signDate,
signRegion,

View file

@ -10,14 +10,24 @@ uses
type
{ TAWSConfig }
{ TAWSCredentialConfig }
TAWSConfig = class
TAWSCredentialConfig = class
private
_versionAlgorithm: String;
_prefix: String;
_service: String;
_request: String;
public
credentialVersionAlgorithm: String;
credentialPrefix: String;
credentialService: String;
credentialRequest: String;
constructor Create(
const versionAlgorithm: String;
const prefix: String;
const service: String;
const request: String );
property versionAlgorithm: String read _versionAlgorithm;
property prefix: String read _prefix;
property service: String read _service;
property request: String read _request;
end;
{ TAWSAccessKey }
@ -28,14 +38,25 @@ type
_secret: String;
public
constructor Create( const id: String; const secret: String );
function clone: TAWSAccessKey;
property id: String read _id;
property secret: String read _secret;
end;
{ TAWSConnectionData }
TAWSConnectionData = record
region: String;
endPoint: String;
defaultBucket: String;
end;
{ TAWSCloudDriver }
TAWSCloudDriver = class( TCloudDriver )
public
function getConnectionData: TAWSConnectionData; virtual; abstract;
procedure setConnectionData( const connectionData: TAWSConnectionData ); virtual; abstract;
function getAccessKey: TAWSAccessKey; virtual; abstract;
procedure setAccessKey( const accessKey: TAWSAccessKey ); virtual; abstract;
end;
@ -65,6 +86,20 @@ const
implementation
{ TAWSCredentialConfig }
constructor TAWSCredentialConfig.Create(
const versionAlgorithm: String;
const prefix: String;
const service: String;
const request: String);
begin
_versionAlgorithm:= versionAlgorithm;
_prefix:= prefix;
_service:= service;
_request:= request;
end;
{ TAWSAccessKey }
constructor TAWSAccessKey.Create( const id: String; const secret: String );
@ -73,5 +108,10 @@ begin
_secret:= secret;
end;
function TAWSAccessKey.clone: TAWSAccessKey;
begin
Result:= TAWSAccessKey.Create( _id, _secret );
end;
end.

View file

@ -21,17 +21,15 @@ uses
type
TS3AccessKey = TAWSAccessKey;
TS3Config = TAWSCredentialConfig;
TS3Config = TAWSConfig;
TS3AuthSessionParams = TAWSAuthSessionParams;
TS3ConfigPtr = ^TS3Config;
{ TS3ListFolderSession }
TS3ListFolderSession = class( TCloudDriverListFolderSession )
private
_params: TS3AuthSessionParams;
_connectionData: TAWSConnectionData;
_continuationToken: String;
private
procedure analyseListResult( const listString: String );
@ -96,6 +94,8 @@ type
function authorized: Boolean; override;
function getAccessKey: TAWSAccessKey; override;
procedure setAccessKey(const accessKey: TAWSAccessKey); override;
function getConnectionData: TAWSConnectionData; override;
procedure setConnectionData(const connectionData: TAWSConnectionData); override;
public
procedure download(
const serverPath: String;
@ -248,7 +248,7 @@ var
queryItems: TQueryItemsDictonary;
begin
try
urlString:= 'https://' + _params.defaultBucket + '.' + _params.endPoint + '/?';
urlString:= 'https://' + _connectionData.defaultBucket + '.' + _connectionData.endPoint + '/?';
queryItems:= TQueryItemsDictonary.Create;
queryItems.Add( 'list-type', '2' );
queryItems.Add( 'delimiter', '/' );
@ -279,7 +279,7 @@ constructor TS3ListFolderSession.Create( const authSession: TCloudDriverAuthSess
var
truePath: String;
begin
_params:= TAWSAuthSession(authSession).params;
_connectionData:= TAWSAuthSession(authSession).connectionData;
truePath:= path;
if truePath.StartsWith( '/' ) then
truePath:= truePath.Substring( 1 );
@ -295,13 +295,13 @@ end;
procedure TS3DownloadSession.download;
var
http: TMiniHttpClient = nil;
params: TS3AuthSessionParams;
connectionData: TAWSConnectionData;
urlString: String;
cloudDriverResult: TCloudDriverResult = nil;
begin
try
params:= TAWSAuthSession(_authSession).params;
urlString:= 'https://' + params.defaultBucket + '.' + params.endPoint + THttpClientUtil.urlEncode(_serverPath);
connectionData:= TAWSAuthSession(_authSession).connectionData;
urlString:= 'https://' + connectionData.defaultBucket + '.' + connectionData.endPoint + THttpClientUtil.urlEncode(_serverPath);
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.GET );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );
@ -321,13 +321,13 @@ end;
procedure TS3UploadSession.upload;
var
http: TMiniHttpClient = nil;
params: TS3AuthSessionParams;
connectionData: TAWSConnectionData;
urlString: String;
cloudDriverResult: TCloudDriverResult = nil;
begin
try
params:= TAWSAuthSession(_authSession).params;
urlString:= 'https://' + params.defaultBucket + '.' + params.endPoint + THttpClientUtil.urlEncode(_serverPath);
connectionData:= TAWSAuthSession(_authSession).connectionData;
urlString:= 'https://' + connectionData.defaultBucket + '.' + connectionData.endPoint + THttpClientUtil.urlEncode(_serverPath);
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.PUT );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );
@ -347,13 +347,13 @@ end;
procedure TS3CreateFolderSession.createFolder;
var
http: TMiniHttpClient = nil;
params: TS3AuthSessionParams;
connectionData: TAWSConnectionData;
urlString: String;
cloudDriverResult: TCloudDriverResult = nil;
begin
try
params:= TAWSAuthSession(_authSession).params;
urlString:= 'https://' + params.defaultBucket + '.' + params.endPoint + THttpClientUtil.urlEncode(_path+'/');
connectionData:= TAWSAuthSession(_authSession).connectionData;
urlString:= 'https://' + connectionData.defaultBucket + '.' + connectionData.endPoint + THttpClientUtil.urlEncode(_path+'/');
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.PUT );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
_authSession.setAuthHeader( http );
@ -373,13 +373,13 @@ end;
procedure TS3DeleteSession.delete;
var
http: TMiniHttpClient = nil;
params: TS3AuthSessionParams;
connectionData: TAWSConnectionData;
urlString: String;
cloudDriverResult: TCloudDriverResult = nil;
begin
try
params:= TAWSAuthSession(_authSession).params;
urlString:= 'https://' + params.defaultBucket + '.' + params.endPoint + THttpClientUtil.urlEncode(_path);
connectionData:= TAWSAuthSession(_authSession).connectionData;
urlString:= 'https://' + connectionData.defaultBucket + '.' + connectionData.endPoint + THttpClientUtil.urlEncode(_path);
if _isFolder then
urlString:= urlString + '/';
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.DELETE );
@ -401,15 +401,15 @@ end;
procedure TS3CopyMoveSession.doCopyFile;
var
http: TMiniHttpClient = nil;
params: TS3AuthSessionParams;
connectionData: TAWSConnectionData;
urlString: String;
cloudDriverResult: TCloudDriverResult = nil;
sourceHeaderString: String;
begin
try
params:= TAWSAuthSession(_authSession).params;
urlString:= 'https://' + params.defaultBucket + '.' + params.endPoint + THttpClientUtil.urlEncode(_toPath);
sourceHeaderString:= '/' + params.defaultBucket + THttpClientUtil.urlEncode(_fromPath);
connectionData:= TAWSAuthSession(_authSession).connectionData;
urlString:= 'https://' + connectionData.defaultBucket + '.' + connectionData.endPoint + THttpClientUtil.urlEncode(_toPath);
sourceHeaderString:= '/' + connectionData.defaultBucket + THttpClientUtil.urlEncode(_fromPath);
http:= TMiniHttpClient.Create( urlString, HttpConst.Method.PUT );
http.addHeader( AWSConst.HEADER.CONTENT_SHA256, AWSConst.HEADER.CONTENT_SHA256_DEFAULT_VALUE );
http.addHeader( AWSConst.HEADER.COPY_SOURCE, sourceHeaderString );
@ -476,6 +476,16 @@ begin
_authSession.accessKey:= accessKey;
end;
function TS3Client.getConnectionData: TAWSConnectionData;
begin
Result:= _authSession.connectionData;
end;
procedure TS3Client.setConnectionData(const connectionData: TAWSConnectionData);
begin
_authSession.connectionData:= connectionData;
end;
procedure TS3Client.download(
const serverPath: String;
const localPath: String;