I have a multi-tenant app in which user can select "current company" after they log in.
There is a DB per company but the model is the same, the workflow is the same, and the controller actions are same....The user can switch companies while being logged in and all actions need to be 'directed' to proper DB.
I know it is possible to customize context creation in EFContextProvider<T> by overriding CreateContext() but how do I pass the extra info (parameter, e.g. CompanyId) that would allow me to create context with correct connection string?
Is this possible?
I find the easiest way is to include the tenant id in a custom HTTP header.
Because the tenant id changes during the session, you probably want to create a custom Breeze ajax adapter (wrap the one you're using now) that sets this header dynamically during its implementation of the ajax method.
On the server you fish the header out of the request.
MAKE SURE YOU ARE VALIDATING USER AND HEADER ON THE SERVER
Related
situation: Lets's think about basic process of object creation on a client (with CRUD backend).
Let's imagine that we have two "Create" buttons on a page.
first case:
Clicking on the first button will cause to redirect to /create route, where our form located.
After we fill the form with data, we post it to a backend and it retrieves an id of a newly created object.
second case:
Clicking on the second button will cause to send creation request to the backend, then after we got a new object id, we will be redirected to /edit/:id, where our form located (same form).
After we fill the form with data, we send it to a backend and save already existed object (post by id).
question:
What's the pros and cons of those two cases, when to use each of them?
In the first case you can include the validation of the fields in the time of creation
and you only need to create an insert so one database call.
In the second case you are creating an empty entry that will appear in the grids of an application with no data.
Also if your database has required fields, you have to fill them with default data.
Validation will be more difficult since you need to allow empty ex Mobile in data entry
while phone might be required.
Another problem with this is that that you are basically doing two operations. One if for the Insert of the row and one is for the update of the row
However this methodology is easier to implement the live update of text when typing so any disconnects etc will not lose any data. This methodology is also good for collaboration between two clients using websockets ex inserting the row at the same time.
I've got Keycloak setup and running with NodeJS.
I see you can create groups and assign attributes to those groups. Is it possible to access these attributes from the NodeJS application?
I can't even find the groups let alone their attributes.
Yes you can. But there is almost no official documentation on how to achieve this. You can return most keycloak attributes, groups and roles through the client mappers. By default none are configured.
To configure extra mappers: In the administration console, select the client and then the Mappers tab. That should bring you to a list of mappers.
You can add mappers here of different types. Once you add a mapper you can decide which calls to Keycloak from the client return the attribute(s), and what the name of the returned attribute is. The following screenshot includes a mapper that returns a dictionary of groups, with subgroups, separated by forward slashes. Your Node code will need to parse the returned JSON object.
All the information is returned in the keycloak token, which is a Javascript Web Token. In Node you can examine it by printing the token to the log. The keycloak-connect middleware stores tokens etc in an object on the request called kauth. The path to retrieve a list of groups specified by the configuration in the above screenshot is shown below. If you change the token claim name in the configuration, you will need to change the path in your NodeJS code accordingly. You will need to logout from your application and login again for changes to the mapper to work.
router.get('/', async function(req, res){
console.log(req.kauth.grant.access_token.content.groups) ..
}
I'm absolutely new of Symfony, and I'm trying to implement a registration form that works only with invitation
but that can redirect two different forms for two different roles.
In practice if I send an invitation for an USER_TYPE1 role the client can only register like USER_TYPE1, if I send an invitation for an USER_TYPE2 the client can only register like USER_TYPE2 (and, of course, assigns the corrispondent role).
Is it possible?
thank you in advance for your help
UPDATE:
I want two different form because one user will be allowed to update file, but will also have to set his position and other important settings. The second user will only allow to download the files uploaded by the first kind of user, and his profile needs completely different information.
I do not have enough reputation to ask for details, but one thing that is not clear in your question is: why do you need 2 different forms? In your question, you mention 2 different roles, but why do you need 2 different forms? If you really need 2 different forms, then you should first:
- create a new form type
- create a new view (twig)
Like Boris suggested, I would keep some kind of token for every invitation sent, and associate an email address, and a role to it. Then modify your registration route so you can pass a token in there, like this:
register:
pattern: /signup/{token}
defaults: { _controller: MyBundle:Registration:signup }
In the registration action of your controller, you created the correct form type and display the appropriate twig, depending on the ROLE associated to the token you just got. And when handling a POST, you check the Token again to see if it matches the email address, and assign the proper ROLE when creating the User.
public function signupAction($token) {
// 1. Get the Token entity matching the $token variable
// 2. Create the correct form type
// 3. Display the correct twig for GET, assign correct ROLE to new User for POST
}
But you can't use FOSUserBundle as-is. You will have to overwrite the registration process. You can read the FOSUserBundle documentation about that.
What's certain is that, for every invitation you send, you should keep a token with a matching email address and ROLE (the role you want to give to that person).
Assume I want to create a very simple todolist RESTful API, where each user owns a list of todos. The user is already authenticated over http BASIC or DIGEST.
At this point I am not sure what the URL scheme should look like.
Would it be:
http://servername/todos/
where my server filters the appropriate todos according to the authentification given to me by the http header.
Or should I include the username in the URI instead:
http://servername/users/username/todos/
On some websites I have even seen that they hand over the user name as a parameter like this:
http://servername/todos?username=babsi
As far as I can tell all three choices are stateless as I always receive the username, but just over different sources. From what I can tell to make sure that the URI is accessed by the proper user I always need to check the http header anyways. So which of the ways would you consider the best URI design in REST or should I do in a different way entirely?
You can use the following:
http://servername/todos/ GET list all todos
http://servername/users/ GET list all users
http://servername/users/{user_id}/ GET list an user
http://servername/users/{user_id}/todos/ GET list all todos for an user
I think the point here is how you want to design the relationships between your resources, if a todo just can exist in the context of an user use a hierarchy like approach as above.
As general rule i usually follow this:
Use path variables to encode hierarchy: /parent/child
Put punctuation characters in path variables to avoid implying hierarchy where
none exists: /parent/child1;child2
Use query variables to imply inputs into an algorithm, for
example: /search?q=jellyfish&start=20
Having the username in the URL depends on what you want to do (if anything at all) when you receive a request where the username in the URL does not match the authentication. If you want to re-authorize the user in this situation then yes - it's OK to have the username in the URL, otherwise it's OK to have it just in your header or other authentication scheme if there is no such need.
One fairly common example of a valid requirement would be if you have to have a main user (or group of such users) that can impersonate other users.
When the user in question is always the user who is holding the authentication token, then use something like "me" in your path.
http://example.com/users/me/<path-to-inner-resource>
Otherwise, user should be treated just like any other resource in your system, in which case the resource identifier for that user becomes a part of the path.
http://example.com/users/<id>/<path-to-inner-resource>
Take a look at Twitter APIs as an example.
https://developer.twitter.com/en/docs/twitter-api/users/follows/quick-start/follows-lookup
I want to make my system redirect unknown requests such as
www.address.com/a_company
to the adress
www.address.com/companies/company/ and display the company a_company if it exists in the database, otherwise throw the user to a 404 not found page.
So in detail, I want to make namespace that is as the first example dynamically, if the company exist in the database, I have no problem connecting to the database and retrieving information or finding a way to parse a company name, I just need help how to make my system check and run a function every time the address doesn't exist and show the second page (/companies/company/)..
I am using an Acl as well, but I think it should be fine if the page is /companies/company and then possibly add /?c=a_company or similar.
Thank you.
/Marcus
simply create a front controller plugin which checks the request params agains the database before the request is dispatched.