# frozen_string_literal: truerequire'aws-sigv4'moduleAwsmodulePlugins# @api privateclassSign<Seahorse::Client::Plugin# These once had defaults. But now they are used as overrides to# new endpoint and auth resolution.option(:sigv4_signer)option(:sigv4_name)option(:sigv4_region)option(:unsigned_operations,default: [])supported_auth_types=%w[sigv4 bearer sigv4-s3express sigv4a none]SUPPORTED_AUTH_TYPES=supported_auth_types.freezedefadd_handlers(handlers,cfg)operations=cfg.api.operation_names-cfg.unsigned_operationshandlers.add(Handler,step: :sign,operations: operations)end# @api private# Return a signer with the `sign(context)` methoddefself.signer_for(auth_scheme,config,sigv4_region_override=nil,sigv4_credentials_override=nil)caseauth_scheme['name']when'sigv4','sigv4a','sigv4-s3express'sigv4_overrides={region: sigv4_region_override,credentials: sigv4_credentials_override}SignatureV4.new(auth_scheme,config,sigv4_overrides)when'bearer'Bearer.newelseNullSigner.newendendclassHandler<Seahorse::Client::Handlerdefcall(context)# Skip signing if using sigv2 signing from s3_signer in S3credentials=nilunlessv2_signing?(context.config)signer=Sign.signer_for(context[:auth_scheme],context.config,context[:sigv4_region],context[:sigv4_credentials])credentials=signer.credentialsifsigner.is_a?(SignatureV4)signer.sign(context)endwith_metrics(credentials){@handler.call(context)}endprivatedefwith_metrics(credentials,&block)returnblock.callunlesscredentials&.respond_to?(:metrics)Aws::Plugins::UserAgent.metric(*credentials.metrics,&block)enddefv2_signing?(config)# 's3' is legacy signing, 'v4' is defaultconfig.respond_to?(:signature_version)&&config.signature_version=='s3'endend# @api privateclassBearerdefinitializeenddefsign(context)ifcontext.http_request.endpoint.scheme!='https'raiseArgumentError,'Unable to use bearer authorization on non https endpoint.'endtoken_provider=context.config.token_providerraiseErrors::MissingBearerTokenErrorunlesstoken_provider&.set?context.http_request.headers['Authorization']="Bearer #{token_provider.token.token}"enddefpresign_url(*args)raiseArgumentError,'Bearer auth does not support presigned urls'enddefsign_event(*args)raiseArgumentError,'Bearer auth does not support event signing'endend# @api privateclassSignatureV4attr_reader:signerdefinitialize(auth_scheme,config,sigv4_overrides={})scheme_name=auth_scheme['name']unless%w[sigv4 sigv4a sigv4-s3express].include?(scheme_name)raiseArgumentError,"Expected sigv4, sigv4a, or sigv4-s3express auth scheme, got #{scheme_name}"endregion=ifscheme_name=='sigv4a'auth_scheme['signingRegionSet'].join(',')elseauth_scheme['signingRegion']endbegin@signer=config.sigv4_signer||Aws::Sigv4::Signer.new(service: config.sigv4_name||auth_scheme['signingName'],region: sigv4_overrides[:region]||config.sigv4_region||region,credentials_provider: sigv4_overrides[:credentials]||config.credentials,signing_algorithm: scheme_name.to_sym,uri_escape_path: !!!auth_scheme['disableDoubleEncoding'],normalize_path: !!!auth_scheme['disableNormalizePath'],unsigned_headers: %w[content-length user-agent x-amzn-trace-id expect transfer-encoding connection])rescueAws::Sigv4::Errors::MissingCredentialsErrorraiseAws::Errors::MissingCredentialsErrorendenddefsign(context)req=context.http_requestapply_authtype(context,req)reset_signature(req)apply_clock_skew(context,req)# compute the signaturebeginsignature=@signer.sign_request(http_method: req.http_method,url: req.endpoint,headers: req.headers,body: req.body)rescueAws::Sigv4::Errors::MissingCredentialsError# Necessary for when credentials is explicitly set to nilraiseAws::Errors::MissingCredentialsErrorend# apply signature headersreq.headers.update(signature.headers)# add request metadata with signature components for debuggingcontext[:canonical_request]=signature.canonical_requestcontext[:string_to_sign]=signature.string_to_signenddefpresign_url(*args)@signer.presign_url(*args)enddefsign_event(*args)@signer.sign_event(*args)enddefcredentials@signer.credentials_providerendprivatedefapply_authtype(context,req)# only used for event streaming at inputifcontext[:input_event_emitter]req.headers['X-Amz-Content-Sha256']='STREAMING-AWS4-HMAC-SHA256-EVENTS'elsifunsigned_payload?(context,req)req.headers['X-Amz-Content-Sha256']||='UNSIGNED-PAYLOAD'endenddefunsigned_payload?(context,req)(context.operation['unsignedPayload']||context.operation['authtype']=='v4-unsigned-body')&&req.endpoint.scheme=='https'enddefreset_signature(req)# in case this request is being re-signedreq.headers.delete('Authorization')req.headers.delete('X-Amz-Security-Token')req.headers.delete('X-Amz-Date')req.headers.delete('x-Amz-Region-Set')enddefapply_clock_skew(context,req)ifcontext.config.respond_to?(:clock_skew)&&context.config.clock_skew&&context.config.correct_clock_skewendpoint=context.http_request.endpointskew=context.config.clock_skew.clock_correction(endpoint)ifskew.abs.positive?req.headers['X-Amz-Date']=(Time.now.utc+skew).strftime('%Y%m%dT%H%M%SZ')endendendend# @api privateclassNullSignerdefsign(context)enddefpresign_url(*args)enddefsign_event(*args)endendendendend