Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,21 @@ Complete the following steps:

##### Note

* _This sample application has been tested in iPhone XS and iPhone 6._
* _This sample application has been tested in Simulator (iPhone 16e) and iPhone SE 2nd Generation._


#### Using user-provided AWS credentials

> [!IMPORTANT]
> This is not recommended for production use.

In the top navigation of the XCode UI, choose "Product" > "Scheme" > "Edit Scheme". Choose "Run", "Environment Variables"
and set the "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", (optional: "AWS_SESSION_TOKEN") environment variables.

In this mode, your `awsconfiguration.json` does not need to be modified, and neither do the `REPLACEME` values
in the `Constants.swift`.

Those user-provided credentials will be used to interact with KVS APIs instead of using credentials fetched from AWS Cognito Service.

## Troubleshooting

Expand Down
15 changes: 15 additions & 0 deletions Swift/KVSiOSApp/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

// Application uses the user provided test IAM credentials through environment (testing only)
if let accessKey = awsAccessKey, !accessKey.isEmpty,
let secretKey = awsSecretKey, !secretKey.isEmpty {
print("⚠️ WARNING: Using static AWS credentials - FOR PROTOTYPING ONLY, DO NOT USE IN PRODUCTION!")

// Skip to channel configuration
self.storyboard = UIStoryboard(name: "Main", bundle: nil)
self.navigationController = self.storyboard?.instantiateViewController(withIdentifier: "channelConfig") as? UINavigationController
self.channelConfigViewController = self.navigationController?.viewControllers[0] as? ChannelConfigurationViewController
DispatchQueue.main.async {
self.window?.rootViewController?.present(self.navigationController!, animated: true, completion: nil)
}
return true
}

// Warn user if configuration not updated
if (cognitoIdentityUserPoolId == "REPLACEME") {
let alertController = UIAlertController(title: "Invalid Configuration",
Expand Down
48 changes: 37 additions & 11 deletions Swift/KVSiOSApp/ChannelConfigurationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate

var peerConnection: RTCPeerConnection?

// Helper function to get appropriate credentials provider
private func getCredentialsProvider() -> AWSCredentialsProvider {
if let accessKey = awsAccessKey, !accessKey.isEmpty,
let secretKey = awsSecretKey, !secretKey.isEmpty {
print("⚠️ WARNING: Using static AWS credentials - FOR PROTOTYPING ONLY, DO NOT USE IN PRODUCTION!")

if let sessionToken = awsSessionToken, !sessionToken.isEmpty {
return AWSBasicSessionCredentialsProvider(accessKey: accessKey, secretKey: secretKey, sessionToken: sessionToken)
} else {
return AWSStaticCredentialsProvider(accessKey: accessKey, secretKey: secretKey)
}
}
return AWSMobileClient.default()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
self.signalingConnected = false
Expand Down Expand Up @@ -94,6 +109,14 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate
}

@IBAction func signOut(_ sender: AnyObject) {

// Disable signout option (n/a) when testing with user provided credentials through environment
if let accessKey = awsAccessKey, !accessKey.isEmpty,
let secretKey = awsSecretKey, !secretKey.isEmpty {
popUpError(title: "Using hard-coded AWS IAM credentials for development testing", message: "Do not use this in production")
return
}

AWSMobileClient.default().signOut()
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
self.present((mainStoryBoard.instantiateViewController(withIdentifier: "signinController") as? UINavigationController)!, animated: true, completion: nil)
Expand Down Expand Up @@ -145,7 +168,7 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate
print("Generated clientID is \(self.localSenderId)")
}
// Kinesis Video Client Configuration
let configuration = AWSServiceConfiguration(region: awsRegionType, credentialsProvider: AWSMobileClient.default())
let configuration = AWSServiceConfiguration(region: awsRegionType, credentialsProvider: getCredentialsProvider())
AWSKinesisVideo.register(with: configuration!, forKey: awsKinesisVideoKey)

// Attempt to retrieve signalling channel. If it does not exist create the channel
Expand Down Expand Up @@ -297,7 +320,7 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate
let configuration =
AWSServiceConfiguration(region: regionType,
endpoint: endpoint,
credentialsProvider: AWSMobileClient.default())
credentialsProvider: getCredentialsProvider())
AWSKinesisVideoSignaling.register(with: configuration!, forKey: awsKinesisVideoKey)
let kvsSignalingClient = AWSKinesisVideoSignaling(forKey: awsKinesisVideoKey)

Expand Down Expand Up @@ -373,13 +396,16 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate

func createSignedWSSUrl(channelARN: String, region: String, wssEndpoint: String?, isMaster: Bool) -> URL? {
// get AWS credentials to sign WSS Url with
var AWSCredentials : AWSCredentials?
AWSMobileClient.default().getAWSCredentials { credentials, _ in
AWSCredentials = credentials
}
var awsCreds : AWSCredentials?

getCredentialsProvider().credentials().continueWith { task in
awsCreds = task.result
return nil
}.waitUntilFinished()

while(AWSCredentials == nil){
usleep(5)
guard awsCreds != nil else {
popUpError(title: "Error fetching credentials", message: "Unable to fetch the credentials")
return nil
}

var httpURlString = wssEndpoint!
Expand All @@ -391,9 +417,9 @@ class ChannelConfigurationViewController: UIViewController, UITextFieldDelegate
let wssRequestURL = URL(string: wssEndpoint!)
let wssURL = KVSSigner
.sign(signRequest: httpRequestURL!,
secretKey: (AWSCredentials?.secretKey)!,
accessKey: (AWSCredentials?.accessKey)!,
sessionToken: (AWSCredentials?.sessionKey)!,
secretKey: (awsCreds?.secretKey)!,
accessKey: (awsCreds?.accessKey)!,
sessionToken: (awsCreds?.sessionKey ?? ""),
wssRequest: wssRequestURL!,
region: region)
return wssURL
Expand Down
3 changes: 3 additions & 0 deletions Swift/KVSiOSApp/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,6 @@ let wssKey = "wss"
let plusEncoding = "%2B"
let equalsEncoding = "%3D"

let awsAccessKey: String? = ProcessInfo.processInfo.environment["AWS_ACCESS_KEY_ID"]
let awsSecretKey: String? = ProcessInfo.processInfo.environment["AWS_SECRET_ACCESS_KEY"]
let awsSessionToken: String? = ProcessInfo.processInfo.environment["AWS_SESSION_TOKEN"]
Loading