Accessing Cognito Custom Attributes in a post-confirmation lambda function - aws-lambda

I have a post-confirmation lambda function that writes user attribute information to a dynamoDB table. I've managed to get access to standard user attributes fields in the "event" parameter by doing stuff like
event.request.userAttributes.sub
but trying to run
event.request.userAttributes.role //where role is the name of my custom attribute
doesn't seem to work. Anyone know what the proper syntax for this is? And do I need to set any special read permissions for custom attributes? I created this custom attribute a long time after I originally made this user pool, if that changes things.

All custom attributes are prefixed with the custom: prefix (Documentation - Custom Attributes).
Therefore (I'll assume you're using JavaScript here- if not feel free to specify and I can change this example), you'd need to use:
event.request.userAttributes['custom:role']
You don't need to set any special read permissions- all the user attributes are returned in the PostConfirmation lambda.

Related

Does the value of global variable persist in multiple API calls

So I have done a lot of research and could not find a proper answer. This might be a bit long post so sorry for that. I am making a backend API using golang. I am using gingonic for routing and api stuffs.
There are 2 part of the service. Application and user. When lets say createAccount endpoint is called from the other micro service, it need to pass the user information and application token in body. Each application is like micro service that is registered to this micro service that I am building and have a unique token. If the token they pass matches then I will get the id of that row and use that to create an entry in user table which will have the id associate with it.
Now for every API call to this micro service, it is important that they are sending the valid token and that row id is needed to do all sort of functionality like login user, edit user info and so on as the each user is connected with that app id by foreign key. Currently, I wrote a middleware and when any api call is made I get row id and save it to a global variable and then when necessary I am using it in any part of the codebase.
Lets say if 5 multiple API call is made, will that global variable information will be persisted or for each call its brand new value? If it is persisted then what can I do to achieve the brand new of Global variable for every API call or if there are better approach can you please recommend it?
A global variable is not the answer here. It will be overwritten by each request as you suspected. Instead, the typical way to handle this situation is to have a context object that is created within the scope of the HTTP Request and passed to each method that requires knowledge of that context.
One basic rule is to AVOID using the global variables, it is bad practices, you cannot manage the state and you are limited for testing and concurrency using.
In my mind come two basic solutions:
Use context for this. In your handler, add the value in context and propagate this context by all your service calls. It is also useful for tracing if you are working with microservices, then you also should take a look for this. And in the place where you need the value from your global variable, do simple call: ctx.Value(YOUR_KEY) Take a look at the end of the page, you shouldn't use string as the key to context values.
You can wrap your data in the struct with this variable value. For example:
type CreateReq struct {
Token string // value from global variable
User user
}
and use this Token in your services.

Can SCIM update non SCIM-created resources?

Specifically, can SCIM be used to add Users to pre-existing (non SCIM-created) groups? We need to provision users via SCIM, but then add them to Groups created manually in the site (a .Net application).
As I understand it, it can't be done like this. Group Update requests (i.e. PATCH requests) seem to require the "id" attribute as the unique identifier for the group, and this "id" seems to be only generated in SCIM Create Requests. So if a Resource (Group / User) wasn't originally created via SCIM, SCIM can't update/replace/delete it. Is that correct?
e.g. PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
I thought about a workaround convention, such as using "user:1234" and "group:1234" as the "id" attribute format (i.e. [resource type]:[internal type-specific ID]), and then any User or Group can be specified by "id", even if it wasn't created via SCIM. But that seems pretty hacky.
Is there a better way of doing this? Many thanks for any help, very new to SCIM!
Yes, SCIM can be used to manage "brownfield" scenarios where existing non-SCIM created objects exist.
Typically the logic flow that happens for a user object is:
GET on /users with a filter (as defined in RFC7644 3.4.2.2) using an attribute that is uniqueness constrained (such as userName, email).
If no user found matching that criteria, create a new user with POST to /users
If a user was found, it should bereturned with an id value even if it was not created via SCIM
The general logic of "Search using a friendly identifier -> create if not found/cache the id value and associated it with existing user in the other directory" is pretty simple and can be successfully used with other object types (ie: groups) as well.

Conditional object ACL

New to Parse, coming from Google Firebase, I am not able to completely wrap my head around the security aspect of the platform, let alone write some code. From Firebase, I'm used to writing security rules, by defining conditions that need to be met for certain actions to be allowed (such as: allow write if owner field of post is equal to the current users uid).
So how would I solve following problem? I have an object Post containing properties title, content, owner, public.
Allow reading under following conditions:
if public == true
or currentUser matches field owner
Allow writing if currentUser matches field owner.
Is there a way to implement this? I have found a solution to restrict writing using Cloud Functions, although I am certain there must be a better way.
Thanks in advance!

Adding attribute to a user when register in Laravel 5.1

When a user Register, I want to add location data for the user.
I get those with GeoIP.
So, each time a user is created, I would like somewhere to add Country, City, etc.
I was thinking about setting Hidden fields in view, but I think it a hugly way to do it, and I'm sure there is a better way to do...
Any Idea???
Any time I create a record that needs extra data, involves inserting additional records into additional tables, etc, I create a service class. Something like "UserCreator" then I pass it the input, do any additional operations, wrap multiple database calls in a transaction and so on.
That said there are so many ways to do what you want. You could Input::merge(...) then save, you could separate the process of creating a user from your controller / route function, etc.
If you are just getting started with Laravel and/or your project is rather simple, then you probably want to look at Input::merge
I solved it using Request Contructor as said here in laracast
In the Form Request's constructor I inject \Illuminate\Http\Request. I can then add my value to the request instance as such:
public function __construct(\Illuminate\Http\Request $request)
{
$request->request->add(['date_of_birth' => implode('-', $request->only('year', 'month', 'day'))]);
}

cakePHP - creating new user account, several problems

I have two tables, users and tokens.
Each user have a activated field and each token have the {id, token, user_id, created} fields.
The way the app should work is:
On the creation, the app will -
make sure that the activated field is empty (to avoid manipulations to the submitted data).
a token will be created in the tokens table.
On update, the app will -
NOT create a new token.
NOT allow an update of any kind to the activated field.
check if a new email has been submitted, and if so: will create a new token and set the activated field to false.
I know how to activate the account through the controller and how to setup the router for that.
What I need is mainly the model configuration.
For example:
I think that the token creation should be done in the afterSave method, so - how do I determine if the method is called by an update or by a create operation?
Thanks for any help
yossi you can also specify the fields that should be saved from the form though - a whitelist of fields it is ok to save in you $this->save() call. That way you can stop a hacker passing an ID in the request, and you should just set it in the controller yourself then with $this->Token->id = whatever you have, I would personally use saveField ('activated) in conjunction with this (just saves a single field!). Fat models is best if you can but get it working first then refactor it if you have got stuck. Better than wasting lots of time writing perfect first time.
You question is unclear. If you have a default value for a field, then why not set it in the database rather than doing something in aftersave? If you need to do something that should be done only in certain circumstances, then write a custom method in your model to perform the tasks you want either on creation or update.
Edit
So, if your record has an id, then you know it exists in the database. So, the simple thing to do is (in any method) check to see if the model has an id field and that it is not empty. If it's empty, then you know that you are creating a record and you can do x task. If it isn't, then do y task.
if(isset($modelData['ModelName']['id']) && !empty($modelData['ModelName']['id'])){
//This is an update
} else {
//This is a new record
}

Resources