Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cognito credential provider support #306

Open
wants to merge 35 commits into
base: secitem_bindings
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b3be803
add cognito credential provider support
xiazhvera Dec 23, 2024
70e4dd6
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Dec 23, 2024
732e885
fix test name
xiazhvera Dec 23, 2024
af00a88
fix shutdown flag
xiazhvera Dec 23, 2024
3e17395
skip the test if env is not set
xiazhvera Dec 24, 2024
d4c6b07
swift lint format
xiazhvera Dec 24, 2024
cddd848
test with new env var
xiazhvera Dec 31, 2024
3ac6ec0
set use xcodebuild
xiazhvera Dec 31, 2024
5b3d2a5
remove cognito test
xiazhvera Dec 31, 2024
5eb25e9
waiting for shutdown credential provider
xiazhvera Dec 31, 2024
eb57164
add scope to make sure the provider released
xiazhvera Dec 31, 2024
d982864
setup ci for xcodebuild
xiazhvera Dec 31, 2024
3b3ded9
Merge branch 'iot_ci_env_var' of https://github.com/awslabs/aws-crt-s…
xiazhvera Dec 31, 2024
95487a4
[WIP]cognito test
xiazhvera Dec 31, 2024
59ac4e4
WIP remove test vars
xiazhvera Dec 31, 2024
4b84fcb
add cognito connecton test
xiazhvera Jan 6, 2025
1895e9a
fix spacing...
xiazhvera Jan 6, 2025
7771fae
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Mar 3, 2025
2bf67e4
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Mar 6, 2025
7899729
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Mar 6, 2025
62c87aa
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Mar 6, 2025
cd00d31
Merge branch 'secitem_bindings' of https://github.com/awslabs/aws-crt…
xiazhvera Mar 6, 2025
65cffef
WIP: enable tests on ios and tvos, update cognito credential provider
xiazhvera Mar 7, 2025
35957bc
fulfill the shutdown callback on failed tests
xiazhvera Mar 7, 2025
e2b816a
revert and disable secitem test
xiazhvera Mar 11, 2025
ff5a4de
test against nw_secitem_test
xiazhvera Mar 11, 2025
52a2cc2
fix secitem compile error
xiazhvera Mar 11, 2025
0e39690
test extend the timeout
xiazhvera Mar 11, 2025
2005830
TEST: enable trace log for ios 13
xiazhvera Mar 12, 2025
60bccb8
TEST: more prints
xiazhvera Mar 12, 2025
5052f42
fix spacing
xiazhvera Mar 12, 2025
1cc8aa8
revert spacing with cognito tests
xiazhvera Mar 12, 2025
c641970
more prints
xiazhvera Mar 12, 2025
876b095
update base socket & log level set to error
xiazhvera Mar 12, 2025
8df642b
fix aws-c-io
xiazhvera Mar 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix spacing
xiazhvera committed Mar 12, 2025
commit 5052f4290602b15452a1e402ec6098207dd61948
146 changes: 73 additions & 73 deletions Source/AwsCommonRuntimeKit/auth/credentials/CredentialsProvider.swift
Original file line number Diff line number Diff line change
@@ -73,13 +73,13 @@ func withOptionalCognitoLoginPair<Result>(
}

public class CredentialsProvider: CredentialsProviding {

let rawValue: UnsafeMutablePointer<aws_credentials_provider>

init(credentialsProvider: UnsafeMutablePointer<aws_credentials_provider>) {
self.rawValue = credentialsProvider
}

/// Retrieves credentials from a provider by calling its implementation of get credentials and returns them to
/// the callback passed in.
///
@@ -96,7 +96,7 @@ public class CredentialsProvider: CredentialsProviding {
}
}
}

deinit {
aws_credentials_provider_release(rawValue)
}
@@ -107,7 +107,7 @@ extension CredentialsProvider {
public struct Source {
let makeProvider: () throws -> UnsafeMutablePointer<aws_credentials_provider>
}

/// Creates a credentials provider that sources the credentials from the provided source
public convenience init(source: Source) throws {
let unsafeProvider = try source.makeProvider()
@@ -128,7 +128,7 @@ extension CredentialsProvider {
var options = aws_credentials_provider_delegate_options(shutdown_options: shutdownOptions,
get_credentials: getCredentialsDelegateFn,
delegate_user_data: providerBox.passUnretained())

guard let provider = aws_credentials_provider_new_delegate(allocator.rawValue, &options) else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
@@ -138,7 +138,7 @@ extension CredentialsProvider {
}

extension CredentialsProvider.Source {

/// Creates a credentials provider containing a fixed set of credentials.
///
/// - Parameters:
@@ -155,7 +155,7 @@ extension CredentialsProvider.Source {
accountId: String? = nil,
shutdownCallback: ShutdownCallback? = nil) -> Self {
Self {

let shutdownCallbackCore = ShutdownCallbackCore(shutdownCallback)
var staticOptions = aws_credentials_provider_static_options()
staticOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()
@@ -177,7 +177,7 @@ extension CredentialsProvider.Source {
return provider
}
}

/// Creates a credentials provider that returns credentials based on environment variable values:
/// - `AWS_ACCESS_KEY_ID`
/// - `AWS_SECRET_ACCESS_KEY`
@@ -188,7 +188,7 @@ extension CredentialsProvider.Source {
/// - Returns: `CredentialsProvider`
/// - Throws: CommonRuntimeError.crtError
public static func `environment`(shutdownCallback: ShutdownCallback? = nil) -> Self {

Self {
let shutdownCallbackCore = ShutdownCallbackCore(shutdownCallback)
var envOptions = aws_credentials_provider_environment_options()
@@ -202,7 +202,7 @@ extension CredentialsProvider.Source {
return provider
}
}

/// Creates a credentials provider that sources credentials from the aws profile and credentials files
/// (by default ~/.aws/profile and ~/.aws/credentials)
///
@@ -224,18 +224,18 @@ extension CredentialsProvider.Source {
profileOptionsC.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()
profileOptionsC.profile_collection_cached = fileBasedConfiguration.rawValue
guard let provider: UnsafeMutablePointer<aws_credentials_provider> = withByteCursorFromStrings(
profileFileNameOverride, { profileCursor in
profileOptionsC.profile_name_override = profileCursor
return aws_credentials_provider_new_profile(allocator.rawValue, &profileOptionsC)
})
profileFileNameOverride, { profileCursor in
profileOptionsC.profile_name_override = profileCursor
return aws_credentials_provider_new_profile(allocator.rawValue, &profileOptionsC)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// The process credentials provider sources credentials from running a command or process.
/// The command to run is sourced from a profile in the AWS config file, using the standard
/// profile selection rules. The profile key the command is read from is "credential_process."
@@ -268,18 +268,18 @@ extension CredentialsProvider.Source {
processOptionsC.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()
processOptionsC.config_profile_collection_cached = fileBasedConfiguration.rawValue
guard let provider: UnsafeMutablePointer<aws_credentials_provider> = withByteCursorFromStrings(
profileFileNameOverride, { profileCursor in
processOptionsC.profile_to_use = profileCursor
return aws_credentials_provider_new_process(allocator.rawValue, &processOptionsC)
})
profileFileNameOverride, { profileCursor in
processOptionsC.profile_to_use = profileCursor
return aws_credentials_provider_new_process(allocator.rawValue, &processOptionsC)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Creates a credentials provider that sources credentials from ec2 instance metadata.
/// It will use IMDSv2 to fetch the credentials.
///
@@ -305,7 +305,7 @@ extension CredentialsProvider.Source {
return provider
}
}

/// Configuration options for a provider that functions as a caching decorator. Credentials sourced through this
/// provider will be cached within it until their expiration time. When the cached credentials expire, new
/// credentials will be fetched when next queried.
@@ -322,20 +322,20 @@ extension CredentialsProvider.Source {
shutdownCallback: ShutdownCallback? = nil) -> Self {
Self {
let shutdownCallbackCore = ShutdownCallbackCore(shutdownCallback)

var cachedOptions = aws_credentials_provider_cached_options()
cachedOptions.source = source.rawValue
cachedOptions.refresh_time_in_milliseconds = refreshTime.millisecond
cachedOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()

guard let provider = aws_credentials_provider_new_cached(allocator.rawValue, &cachedOptions) else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Creates the default provider chain used by most AWS SDKs.
/// Generally:
/// - Environment
@@ -356,13 +356,13 @@ extension CredentialsProvider.Source {
shutdownCallback: ShutdownCallback? = nil) -> Self {
Self {
let shutdownCallbackCore = ShutdownCallbackCore(shutdownCallback)

var chainDefaultOptions = aws_credentials_provider_chain_default_options()
chainDefaultOptions.bootstrap = bootstrap.rawValue
chainDefaultOptions.profile_collection_cached = fileBasedConfiguration.rawValue
chainDefaultOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()
chainDefaultOptions.tls_ctx = tlsContext?.rawValue

guard let provider = aws_credentials_provider_new_chain_default(allocator.rawValue,
&chainDefaultOptions)
else {
@@ -372,7 +372,7 @@ extension CredentialsProvider.Source {
return provider
}
}

/// Creates a credentials provider that sources credentials from IoT Core.
/// The x509 credentials provider sources temporary credentials from AWS IoT Core using TLS mutual authentication.<br>
/// See details: [link](https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html)<br>
@@ -398,11 +398,11 @@ extension CredentialsProvider.Source {
shutdownCallback: ShutdownCallback? = nil) -> Self {
Self {
let shutdownCallbackCore = ShutdownCallbackCore(shutdownCallback)

var x509Options = aws_credentials_provider_x509_options()
x509Options.bootstrap = bootstrap.rawValue
x509Options.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()

guard let provider: UnsafeMutablePointer<aws_credentials_provider> =
withByteCursorFromStrings(
thingName,
@@ -414,19 +414,19 @@ extension CredentialsProvider.Source {
return withOptionalCStructPointer(
proxyOptions,
tlsConnectionOptions) { proxyOptionsPointer, tlsConnectionOptionsPointer in
x509Options.proxy_options = proxyOptionsPointer
x509Options.tls_connection_options = tlsConnectionOptionsPointer
return aws_credentials_provider_new_x509(allocator.rawValue, &x509Options)
}})

x509Options.proxy_options = proxyOptionsPointer
x509Options.tls_connection_options = tlsConnectionOptionsPointer
return aws_credentials_provider_new_x509(allocator.rawValue, &x509Options)
}})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Creates a provider that sources credentials from STS using AssumeRoleWithWebIdentity
///
/// Sts with web identity credentials provider sources a set of temporary security credentials for users who have been
@@ -473,25 +473,25 @@ extension CredentialsProvider.Source {
stsOptions.config_profile_collection_cached = fileBasedConfiguration.rawValue
stsOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()
guard let provider: UnsafeMutablePointer<aws_credentials_provider> = withByteCursorFromStrings(
region,
roleArn,
roleSessionName,
tokenFilePath, { regionCursor, roleArnCursor, roleSessionNameCursor, tokenFilePathCursor in
stsOptions.region = regionCursor
stsOptions.role_arn = roleArnCursor
stsOptions.role_session_name = roleSessionNameCursor
stsOptions.token_file_path = tokenFilePathCursor
return aws_credentials_provider_new_sts_web_identity(allocator.rawValue,
&stsOptions)
})
region,
roleArn,
roleSessionName,
tokenFilePath, { regionCursor, roleArnCursor, roleSessionNameCursor, tokenFilePathCursor in
stsOptions.region = regionCursor
stsOptions.role_arn = roleArnCursor
stsOptions.role_session_name = roleSessionNameCursor
stsOptions.token_file_path = tokenFilePathCursor
return aws_credentials_provider_new_sts_web_identity(allocator.rawValue,
&stsOptions)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Creates a provider that that sources credentials using GetRoleCredentialsRequest to the AWS Single
/// Sign-On Service to maintain short-lived sessions.
/// [Details link](https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html)
@@ -515,20 +515,20 @@ extension CredentialsProvider.Source {
ssoOptions.tls_ctx = tlsContext.rawValue
ssoOptions.config_file_cached = fileBasedConfiguration.rawValue
ssoOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()

guard let provider: UnsafeMutablePointer<aws_credentials_provider> = withByteCursorFromStrings(
profileFileNameOverride, { profileCursor in
ssoOptions.profile_name_override = profileCursor
return aws_credentials_provider_new_sso(allocator.rawValue, &ssoOptions)
})
profileFileNameOverride, { profileCursor in
ssoOptions.profile_name_override = profileCursor
return aws_credentials_provider_new_sso(allocator.rawValue, &ssoOptions)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Creates a provider that assumes an IAM role via. STS AssumeRole() API. This provider will fetch new credentials
/// upon each call to `getCredentials`
/// - Parameters:
@@ -556,22 +556,22 @@ extension CredentialsProvider.Source {
stsOptions.creds_provider = credentialsProvider.rawValue
stsOptions.duration_seconds = UInt16(duration)
stsOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()

guard let provider: UnsafeMutablePointer<aws_credentials_provider> = withByteCursorFromStrings(
roleArn,
sessionName, { roleArnCursor, sessionNameCursor in
stsOptions.role_arn = roleArnCursor
stsOptions.session_name = sessionNameCursor
return aws_credentials_provider_new_sts(allocator.rawValue, &stsOptions)
})
roleArn,
sessionName, { roleArnCursor, sessionNameCursor in
stsOptions.role_arn = roleArnCursor
stsOptions.session_name = sessionNameCursor
return aws_credentials_provider_new_sts(allocator.rawValue, &stsOptions)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
}
return provider
}
}

/// Credential Provider that sources credentials from ECS container metadata
/// ECS creds provider can be used to access creds via either relative uri to a fixed endpoint http://169.254.170.2,
/// or via a full uri specified by environment variables:
@@ -605,17 +605,17 @@ extension CredentialsProvider.Source {
ecsOptions.tls_ctx = tlsContext?.rawValue
ecsOptions.bootstrap = bootstrap.rawValue
ecsOptions.shutdown_options = shutdownCallbackCore.getRetainedCredentialProviderShutdownOptions()

guard let provider: UnsafeMutablePointer<aws_credentials_provider> = (withByteCursorFromStrings(
host,
authToken,
pathAndQuery) { hostCursor, authTokenCursor, pathAndQueryCursor in
ecsOptions.host = hostCursor
ecsOptions.auth_token = authTokenCursor
ecsOptions.path_and_query = pathAndQueryCursor
return aws_credentials_provider_new_ecs(allocator.rawValue, &ecsOptions)
})

ecsOptions.host = hostCursor
ecsOptions.auth_token = authTokenCursor
ecsOptions.path_and_query = pathAndQueryCursor
return aws_credentials_provider_new_ecs(allocator.rawValue, &ecsOptions)
})
else {
shutdownCallbackCore.release()
throw CommonRunTimeError.crtError(CRTError.makeFromLastError())
@@ -688,13 +688,13 @@ extension CredentialsProvider.Source {
private func onGetCredentials(credentials: OpaquePointer?,
errorCode: Int32,
userData: UnsafeMutableRawPointer!) {

let continuationCore = Unmanaged<ContinuationCore<Credentials>>.fromOpaque(userData).takeRetainedValue()
if errorCode != AWS_OP_SUCCESS {
continuationCore.continuation.resume(throwing: CommonRunTimeError.crtError(CRTError(code: errorCode)))
return
}

// Success
continuationCore.continuation.resume(returning: Credentials(rawValue: credentials!))
}
@@ -708,9 +708,9 @@ struct SendablePointer: @unchecked Sendable {

private func getCredentialsDelegateFn(_ delegatePtr: UnsafeMutableRawPointer!,
_ callbackFn: (@convention(c) (
OpaquePointer?,
Int32,
UnsafeMutableRawPointer?) -> Void)!,
OpaquePointer?,
Int32,
UnsafeMutableRawPointer?) -> Void)!,
_ userData: UnsafeMutableRawPointer!) -> Int32 {
let delegate = Unmanaged<Box<CredentialsProviding>>
.fromOpaque(delegatePtr)
1,278 changes: 567 additions & 711 deletions Test/AwsCommonRuntimeKitTests/mqtt/Mqtt5ClientTests.swift

Large diffs are not rendered by default.


Unchanged files with check annotations Beta

}
guard payload.withAWSByteBufPointer({ byteBuff in
// TODO (optimization): we could avoid the extra copies of headers and data

Check warning on line 35 in Source/AwsCommonRuntimeKit/event-stream/EventStreamMessage.swift

GitHub Actions / lint

Todo Violation: TODOs should be resolved ((optimization): we could avoid...) (todo)
// if there were an API in C that let us encode everything directly into a pre-allocated buffer
aws_event_stream_message_init(&rawValue, allocator.rawValue, &rawHeaders, byteBuff)
}) == AWS_OP_SUCCESS else {
/// The initial connection flow-control window is 65,535. It is not controllable.
/// Once the connection's flow-control window reaches to 0, all the streams on the connection stop receiving any
/// further data.
/// The user must call aws_http2_connection_update_window() to increment the connection's // TODO: update

Check warning on line 73 in Source/AwsCommonRuntimeKit/http/HTTP2StreamManagerOptions.swift

GitHub Actions / lint

Todo Violation: TODOs should be resolved (update) (todo)
/// window and keep data flowing.
/// Note: the padding of data frame counts to the flow-control window.
/// But, the client will always automatically update the window for padding even for manual window update.
}
let data = Data(bytesNoCopy: self.ptr, count: self.len, deallocator: .none)
return String(decoding: data, as: UTF8.self)

Check warning on line 197 in Source/AwsCommonRuntimeKit/crt/Utilities.swift

GitHub Actions / lint

Optional Data -> String Conversion Violation: Prefer failable `String(bytes:encoding:)` initializer when converting `Data` to `String` (optional_data_string_conversion)
}
func toOptionalString() -> String? {
}
}
// swiftlint:disable type_body_length

Check warning on line 135 in Source/AwsCommonRuntimeKit/crt/CBOR.swift

GitHub Actions / lint

Superfluous Disable Command Violation: SwiftLint rule 'type_body_length' did not trigger a violation in the disabled region; remove the disable command (superfluous_disable_command)
/// Decoder for the CBOR encoding.
public class CBORDecoder {
var rawValue: OpaquePointer
_willDelayIntervalSec,
self.receiveMaximum,
self.maximumPacketSize) { sessionExpiryIntervalSecPointer,
requestResponseInformationPointer,

Check warning on line 155 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
requestProblemInformationPointer,

Check warning on line 156 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
willDelayIntervalSecPointer,

Check warning on line 157 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
receiveMaximumPointer,

Check warning on line 158 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
maximumPacketSizePointer in

Check warning on line 159 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
raw_connect_options.session_expiry_interval_seconds = sessionExpiryIntervalSecPointer
raw_connect_options.request_response_information = requestResponseInformationPointer
self.httpProxyOptions,
self.topicAliasingOptions,
connnectOptions) { socketOptionsCPointer,
tlsOptionsCPointer,

Check warning on line 452 in Source/AwsCommonRuntimeKit/mqtt/Mqtt5Options.swift

GitHub Actions / lint

Closure Parameter Position Violation: Closure parameters should be on the same line as opening brace (closure_parameter_position)
httpProxyOptionsCPointer,
topicAliasingOptionsCPointer,
connectOptionsCPointer in