How to Put Events to custom bus using aws php sdk? - amazon-web-services

I am trying to send an event to custom event bus 'custom-event-bus' using AWS PHP SDK using the following code
$client->putEvents([
'Entries' => [ // REQUIRED
[
'Detail' => '{"alpha":"beta"}',
'DetailType' => '',
'EventBusName' => 'custom-event-bus',
'Resources' => ['arn:aws:events:us-east-1:351123639451:event-bus/custom-event-bus',],
'Source' => 'my-application',
'Time' => time(),
],
],
]);
I am getting this error in the result:
AccessDeniedException (client): User: arn:aws:iam::351123639451:user/my-user is not authorized to perform: events:PutEvents on resource: arn:aws:events:us-east-1:351123639451:event-bus/default - {"__type":"AccessDeniedException","Message":"User: arn:aws:iam::351123639451:user/my-user is not authorized to perform: events:PutEvents on resource: arn:aws:events:us-east-1:351123639451:event-bus/default"}
From this error message, it seems to be that it is sending an event on the default event bus, not the custom one to which I am sending.

The syntax here is correct, EventBusName is where you would specify the event bus name.
I would recommend checking that you have no other calls to this function name, perhaps taking it out and running independently.

Related

How can I attach an IoT Core policy to a Cognito Identity Id on a post authentication Lambda trigger for an Amplify deployed web application?

Situation:
I have a ReactJS web application that is deployed through AWS Amplify and uses Amplify Studio backend to handle authentication through Cognito services and aws-amplify sdk (sign in, sign up).
The web application also implements the use of react native aws-amplify sdk pubsub to subscribe to an MQTT topic in IoT Core and retrieve messages but only to authenticated users.
As per step 2 in the pubsub documentation: Attach your policy to your Amazon Cognito Identity.
If I use the AWS CLI to attach the IoT policy to the user and then I sign in with that user through the web application I am able to successfully subscribe and receive MQTT messages -- it works perectly!
Problem:
The application allows Cognito self-service user sign up (Self-registration) and expects to have many users.
I implemented a post authentication lambda trigger function in the Cognito user pool created by the Amplify service.
The lambda function runs the following sample from AWS documentation with two (2) additional console logs:
exports.handler = (event, context, callback) => {
// Send post authentication data to Cloudwatch logs
console.log ("Authentication successful");
console.log ("Trigger function =", event.triggerSource);
console.log ("User pool = ", event.userPoolId);
console.log ("App client ID = ", event.callerContext.clientId);
console.log ("User ID = ", event.userName);
*** console.log("Event = ", event);
console.log("Context = ", context);***
// Return to Amazon Cognito
callback(null, event);
};
I then authenticate with the user again through the application and go to CloudWatch logs for that Lambda function.
This is the information I get from logging Event and Context after post authentication trigger:
Event log:
{
version: '1',
region: 'us-east-1',
userPoolId: 'us-east-1_*********',
userName: '4eea4a48-92b6-45da-b26e-*********',
callerContext: {
awsSdkVersion: 'aws-sdk-unknown-unknown',
clientId: '*********'
},
triggerSource: 'PostAuthentication_Authentication',
request: {
userAttributes: {
sub: '4eea4a48-92b6-45da-b26e-*********',
'cognito:email_alias': '*********.com',
'cognito:user_status': 'CONFIRMED',
email_verified: 'true',
name: 'asdfasdf',
email: '*********.com'
},
newDeviceUsed: false
},
response: {}
}
Context log:
{
callbackWaitsForEmptyEventLoop: [Getter/Setter],
succeed: [Function (anonymous)],
fail: [Function (anonymous)],
done: [Function (anonymous)],
functionVersion: '$LATEST',
functionName: 'userAccess_iotCore_attachPolicyToCognitoIdentityID',
memoryLimitInMB: '128',
logGroupName: '/aws/lambda/userAccess_iotCore_attachPolicyToCognitoIdentityID',
logStreamName: '2023/01/13/[$LATEST]4eb4287aa4db4dd8a6b6efd810a7***',
clientContext: undefined,
identity: undefined,
invokedFunctionArn: 'arn:aws:lambda:us-east-1:*********:function:userAccess_iotCore_attachPolicyToCognitoIdentityID',
awsRequestId: 'bf6afd1c-117c-4a9e-9d3b-*********',
getRemainingTimeInMillis: [Function: getRemainingTimeInMillis]
}
The big issue here is that context.identity is undefined so I am not able to get that authenticated user's Amazon Cognito Identity Id to attach the required IoT policy for PubSub to work through the application.
Questions:
How can I get the Amazon Cognito Identity Id after post authentication trigger to then attach an IoT policy?
From the web application using the aws-amplify sdk I am able to get this Id after sign in. Is there any API I can use from the application to attach this policy?
Thanks.

Unable to create a scheduler using the #google-cloud/scheduler package

GOT this error while creating a scheduler , earlier i got the code on local and it was working but when i deployed the code on vm on gcp itself it started failing and showed this error.
Error: 7 PERMISSION_DENIED: Request had insufficient authentication scopes.
at Object.callErrorFromStatus (/app/node_modules/#grpc/grpc-js/build/src/call.js:31:26)
at Object.onReceiveStatus (/app/node_modules/#grpc/grpc-js/build/src/client.js:180:52)
at Object.onReceiveStatus (/app/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:336:141)
at Object.onReceiveStatus (/app/node_modules/#grpc/grpc-js/build/src/client-interceptors.js:299:181)`enter code here`
at /app/node_modules/#grpc/grpc-js/build/src/call-stream.js:160:78
at processTicksAndRejections (internal/process/task_queues.js:79:11) {
code: 7,
details: 'Request had insufficient authentication scopes.',
metadata: Metadata {
internalRepr: Map {
'google.rpc.errorinfo-bin' => [Array],
'grpc-status-details-bin' => [Array],
'grpc-server-stats-bin' => [Array]
},
options: {}
},
statusDetails: [
ErrorInfo {
metadata: [Object],
reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
domain: 'googleapis.com'
}
],
reason: 'ACCESS_TOKEN_SCOPE_INSUFFICIENT',
domain: 'googleapis.com',
errorInfoMetadata: {
service: 'cloudscheduler.googleapis.com',
method: 'google.cloud.scheduler.v1.CloudScheduler.CreateJob'`enter code here`
}
}
If you use the default service account on your compute instance, you have to update the scopes; add all or only the Cloud Scheduler one.
If you don't use the default service account, you haven't scopes to select (scopes selection is a legacy mode, no longer available with new feature).
Note You have to stop the VM, change the scopes/service account and then restart the VM

Issue with EventBridge rule for aws.events

I want to send to CloudWatch logs ALL the events sent to a custom event bus.
I created the custom event bus: my-event-bus
I created the CloudWatch log group
I created the event bus policy so everyone within my account can put an event into my-event-bus
I created a rule for that custom bus
This is the rule:
MyRuleForBus:
Type: AWS::Events::Rule
Properties:
Description: Testing rule
EventBusName:
Name: testing-rule-for-my-event-bus
EventPattern:
source:
- aws.events
State: ENABLED
Targets:
- Arn: arn:aws:logs:us-east-1:MY_ACCOUNT_ID:log-group:my-event-bus-log-group
Id: 'my-bus'
When I try to put an event
aws events put-events --entries file://put-events.json
I receive the following error
{
"FailedEntryCount": 1,
"Entries": [
{
"ErrorCode": "NotAuthorizedForSourceException",
"ErrorMessage": "Not authorized for the source."
}
]
}
This is the content of put-events.json
[
{
"Source": "aws.events",
"EventBusName": "my-event-bus",
"Detail": "{ \"key1\": \"value3\", \"key2\": \"value4\" }",
"Resources": [
"resource1",
"resource2"
],
"DetailType": "myDetailType"
}
]
But, if I change the source to other, for example, 'hello', in both, the rule and the event it works.
What am I doing wrong?
I want to make it work with aws.events so all the events sent to this bus end in CloudWatch (target)
aws.events belongs to AWS, not to you, thus you can't define it as source of your events. Only AWS can do it.
You need to use your own custom name for the source of your events, e.g. myapp.events.

Cannot get simple AWS web socket publish to work

I wrote this uber simple client to publish a message to aws sdk via websocket protocol (javascript version). https://github.com/aws/aws-iot-device-sdk-js
var awsIot = require('aws-iot-device-sdk');
var device = awsIot.device({
region: "us-west-2",
protocol: "wss",
clientId: "ARUNAVS SUPER TEST",
host: "iot.us-west-2.amazonaws.com",
port: "443"
});
device
.on('connect', function() {
console.log('connect');
device.publish('abcd', JSON.stringify({ test_data: 1}));
});
device
.on('message', function(topic, payload) {
console.log('message', topic, payload.toString());
});
device
.on('error', function(error) {
console.log('error', error);
});
I am getting the following error (after importing admin creds https://github.com/aws/aws-iot-device-sdk-js#websockets):-
node testCode.js
error { Error: unexpected server response (403)
at ClientRequest._req.on
(/Users/arunavs/mrtests/node_modules/ws/lib/WebSocket.js:653:21)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at HTTPParser.parserOnIncomingClient (_http_client.js:472:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:105:23)
at TLSSocket.socketOnData (_http_client.js:361:20)
at emitOne (events.js:96:13)
at TLSSocket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:177:18)
at TLSSocket.Readable.push (_stream_readable.js:135:10)
type: 'error',
target:
WebSocket {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
readyState: 3,
bytesReceived: 0,
extensions: null,
protocol: '',
_binaryType: 'arraybuffer',
_finalize: [Function: bound finalize],
_closeFrameReceived: false,
_closeFrameSent: false,
_closeMessage: '',
_closeTimer: null,
_finalized: true,
The SDK fails to give any reason why I am getting a 403.
Note : According to https://github.com/aws/aws-iot-device-sdk-js/blob/234d170c865586f4e49e4b0946100d93f367ee8f/device/index.js#L142, the code is even presigning using sigv4, as part of my output also has
url: 'wss://iot.us-west-2.amazonaws.com:443/mqtt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential= .......
Has anyone seen an error like this?
I think, you are publish on the THING which does not allow all users to connect with it.
Can you post the details of the policy of the thing that you are trying to publish message on.
On the Create a policy page, in the Name field, type a name for the
policy (for example, MyIoTButtonPolicy). In the Action field, type
iot:Connect. In the Resource ARN field, type *. Select the Allow
checkbox. This allows all clients to connect to AWS IoT.
Read more about POLICIES.
PS: This is just a wild guess. Please post policy details in the question so that I can be sure.

AWS Amplify React Native, GET request error 403 status code

I enabled access to unauthenticated identities to do some quick testing before integrating authentication. My configuration code is the following,
Amplify.configure({
Auth: {
identityPoolId: 'us-east-1:example',
region: 'us-east-1',
userPoolId: 'us-east-1_example',
userPoolWebClientId: 'us-east-1_example'
},
API: {
endpoints: [
{
name: "example-name",
endpoint: "https://example.execute-api.us-east-1.amazonaws.com/prod/example-path"
},
]
}
});
and my GET request code is the following,
example() {
const apiName = 'example-name';
const path = '/example-path';
API.get(apiName, path).then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
}
I followed everything on GitHub and my API gateway and Lambda functions are working correctly when I run a "test" and through postman. But on react-native it's giving me a 403 status code without any detailed explanation. Does this have to do with accessing using unauthenticated identity? Also, I used "example" in my code to hide my personal information, I typed in everything correctly since I'm not getting any syntax error (identity pool recognizes access every time I run it, but cloudWatch doesn't show any log of gateway access)
The Endpoint in Amplify.configure is the InvokeURL from API Gateway, you just need to include the stage (/prod in this case) and not the other routes. The other routes are just the path parameters for API.() calls.