AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2025-04-18 · Documentation low

File: code-library/latest/ug/swift_1_sns_code_examples.md

Summary

Added a new 'Scenarios' section demonstrating SNS/SQS integration including topic creation, queue subscription with filtering, message publishing, and queue polling

Security assessment

The change adds documentation about setting queue policies that restrict message sending to only the SNS topic (security through resource policies), which is a security best practice. However, there's no evidence this addresses a specific security vulnerability.

Diff

diff --git a/code-library/latest/ug/swift_1_sns_code_examples.md b/code-library/latest/ug/swift_1_sns_code_examples.md
index 26036ed2a..fe1fb15bc 100644
--- a//code-library/latest/ug/swift_1_sns_code_examples.md
+++ b//code-library/latest/ug/swift_1_sns_code_examples.md
@@ -5 +5 @@
-Actions
+ActionsScenarios
@@ -14,0 +15,2 @@ _Actions_ are code excerpts from larger programs and must be run in context. Whi
+_Scenarios_ are code examples that show you how to accomplish specific tasks by calling multiple functions within a service or combined with other AWS services.
+
@@ -150,0 +153,2 @@ The main Swift program.
+  * Scenarios
+
@@ -391,0 +396,746 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+## Scenarios
+
+The following code example shows how to:
+
+  * Create topic (FIFO or non-FIFO).
+
+  * Subscribe several queues to the topic with an option to apply a filter.
+
+  * Publish messages to the topic.
+
+  * Poll the queues for messages received.
+
+
+
+
+**SDK for Swift**
+    
+
+###### Note
+
+There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift/example_code/sqs/scenario#code-examples). 
+    
+    
+    import ArgumentParser
+    import AWSClientRuntime
+    import AWSSNS
+    import AWSSQS
+    import Foundation
+    
+    struct ExampleCommand: ParsableCommand {
+        @Option(help: "Name of the Amazon Region to use")
+        var region = "us-east-1"
+    
+        static var configuration = CommandConfiguration(
+            commandName: "queue-scenario",
+            abstract: """
+            This example interactively demonstrates how to use Amazon Simple
+            Notification Service (Amazon SNS) and Amazon Simple Queue Service
+            (Amazon SQS) together to publish and receive messages using queues.
+            """,
+            discussion: """
+            Supports filtering using a "tone" attribute.
+            """
+        )
+    
+        /// Prompt for an input string. Only non-empty strings are allowed.
+        /// 
+        /// - Parameter prompt: The prompt to display.
+        ///
+        /// - Returns: The string input by the user.
+        func stringRequest(prompt: String) -> String {
+            var str: String?
+    
+            while str == nil {
+                print(prompt, terminator: "")
+                str = readLine()
+    
+                if str != nil && str?.count == 0 {
+                    str = nil
+                }
+            }
+    
+            return str!
+        }
+    
+        /// Ask a yes/no question.
+        /// 
+        /// - Parameter prompt: A prompt string to print.
+        ///
+        /// - Returns: `true` if the user answered "Y", otherwise `false`.
+        func yesNoRequest(prompt: String) -> Bool {
+            while true {
+                let answer = stringRequest(prompt: prompt).lowercased()
+                if answer == "y" || answer == "n" {
+                    return answer == "y"
+                }
+            }
+        }
+    
+        /// Display a menu of options then request a selection.
+        /// 
+        /// - Parameters:
+        ///   - prompt: A prompt string to display before the menu.
+        ///   - options: An array of strings giving the menu options.
+        ///
+        /// - Returns: The index number of the selected option or 0 if no item was
+        ///   selected.
+        func menuRequest(prompt: String, options: [String]) -> Int {
+            let numOptions = options.count
+    
+            if numOptions == 0 {
+                return 0
+            }
+    
+            print(prompt)
+    
+            for (index, value) in options.enumerated() {
+                print("(\(index)) \(value)")
+            }
+    
+            repeat {
+                print("Enter your selection (0 - \(numOptions-1)): ", terminator: "")
+                if let answer = readLine() {
+                    guard let answer = Int(answer) else {
+                        print("Please enter the number matching your selection.")
+                        continue
+                    }
+    
+                    if answer >= 0 && answer < numOptions {
+                        return answer
+                    } else {
+                        print("Please enter the number matching your selection.")
+                    }
+                }
+            } while true
+        }
+        
+        /// Ask the user too press RETURN. Accepts any input but ignores it.
+        /// 
+        /// - Parameter prompt: The text prompt to display.
+        func returnRequest(prompt: String) {
+            print(prompt, terminator: "")
+            _ = readLine()
+        }
+    
+        var attrValues = [
+            "<none>",
+            "cheerful",
+            "funny",
+            "serious",
+            "sincere"
+        ]
+    
+        /// Ask the user to choose one of the attribute values to use as a filter.
+        /// 
+        /// - Parameters:
+        ///   - message: A message to display before the menu of values.
+        ///   - attrValues: An array of strings giving the values to choose from.
+        /// 
+        /// - Returns: The string corresponding to the selected option.
+        func askForFilter(message: String, attrValues: [String]) -> String? {
+            print(message)
+            for (index, value) in attrValues.enumerated() {
+                print("  [\(index)] \(value)")
+            }
+    
+            var answer: Int?
+            repeat {
+                answer = Int(stringRequest(prompt: "Select an value for the 'tone' attribute or 0 to end: "))
+            } while answer == nil || answer! < 0 || answer! > attrValues.count + 1
+    
+            if answer == 0 {
+                return nil
+            }
+            return attrValues[answer!]
+        }
+    
+        /// Prompts the user for filter terms and constructs the attribute
+        /// record that specifies them.
+        /// 
+        /// - Returns: A mapping of "FilterPolicy" to a JSON string representing
+        ///   the user-defined filter.
+        func buildFilterAttributes() -> [String:String] {
+            var attr: [String:String] = [:]
+            var filterString = ""
+    
+            var first = true
+    
+            while let ans = askForFilter(message: "Choose a value to apply to the 'tone' attribute.",
+                                        attrValues: attrValues) {
+                if !first {
+                    filterString += ","
+                }
+                first = false
+    
+                filterString += "\"\(ans)\""
+            }
+    
+            let filterJSON = "{ \"tone\": [\(filterString)]}"
+            attr["FilterPolicy"] = filterJSON
+    
+            return attr
+        }
+        /// Create a queue, returning its URL string.
+        ///
+        /// - Parameters: