Assign Orion entities to users - fiware

I have switched our wirecloud instance login to Fiware IdM. I have there widget connected to Orion using NGSI source operator. My question is how to assign entities in context broker to user - to different users see different entities.

Probably the best way to implement this is by adding a "users" attribute to the entities. This "users" attribute would contain the white list of users with access to that entity.
The main problem for applying this solutions is that the current version of Orion (0.23) doesn't support searching entities using filters. Next versions of Orion are going to provide that functionality (see
#fganlan answer to this question) so you have to wait until this functionality is ready.
If you need this feature now, the only viable solution that I see is to add an attribute per user with access to the entity (the value associated with this attribute is irrelevant) as orion allows filtering entities using a list of attributes, so you can query orion context broker asking for entities containing the attribute associated to the user, if the entity doesn't contain that attribute is not accesible to that user and filtered.
See this question about how to obtain logged user info from widgets.

Related

Clean way to create multiple resources (different types) with an API

For the development of an API we want to create a new organization and a new user for that organization with one form submission (the registration) using a clean RESTful API design.
As we don't want to mix different resources (organizations and users) and create the them with one call (the response of that call is it an organization or an user?) we need to split the registration into two calls: create organization first and directly after create user.
But if the user and organization creation is split into two independent API calls we see the following problems:
How to handle errors? Eg. if the create organization is successful but the create user fails due to an error (eg. user email already exists). In that case an organization without any user is created and nobody can login to change the organization resource.
How to handle the authorization after creating the organization? Can everybody with the organization id simply create a new user without any login check (login is only possible with email and password)? Or will the create organization return a token to create the first user? (The token logic will make the client quite complicated: how to handle resubmissions etc.)
How to handle errors? Eg. if the create organization is successful but the create user fails due to an error (eg. user email already exists). In that case an organization without any user is created and nobody can login to change the organization resource
Except for PATCH none of the standard HTTP methods really tackles a transactional behavior. PATCH i.e. demands that all of the instruction steps defined within the patch document need to be processed atomically. Either all or none of them have to be applied. So if one instruction fails none of the modifications must be applied. The difference between PATCH and the other methods however is, that PATCH should contain a set of instructions to apply onto one or multiple resources while the other operation in a sense target a single document usually.
If viewed from a document management system, which HTTP truely is at its heart as any business rules you conclude are just a side-effect of the document management (see this great talk), the operations of HTTP make a bit more sense. I.e. PUT replaces the current document with the one provided. If none existed so far it is similar to a document creation. The spec here mentions that PUT is allowed to have side-effects. I.e. similar to GIT where a commit will push the head forward though the actual commit will still be accessible via its own URI. DELETE removes the association of the URI to the document stored. Whether that leads to a document removal on the imaginary filesystem or not is an implementation detail. GET will only return the content of that document to the invoker and POST only processes the request according to the service own semantics giving no further promises on what it does with the payload. So whether one or multiple resources are created, or even none at all, is up to the implementation. However, if you create resources you need to return a 201 Created response containing a Location header with the URI of the newly created resource that hints clients about the newly created resource. In the case of multiple resources being created, the spec is a bit less clear what should be returned in that case as only one Location header may appear within the respone.
The usage of a form-based creation approach is for sure a RESTful approach as here the server teaches a client on the needed inputs to perform the task. A client usually isn't that much interested in how the server is actually processing and storing the data, all it is interested in is the completion of its request, either successfully or with a hint on the problems the server had while processing the request.
Whether you create everything in one go or divide each part to its own request is some choice you have to make. I.e. on a typical Web site you may encounter a wizzard like approach were you enter some organization related information first into a form, click a submit button and then get a further form response asking you to enter user details with a further response summarizing the details and asking for confirmation. The data could be stored in some temporary resource that on confirming the summary will create everything in one go mimicking some kind of atomic processing failing the creation of the organization in case some problems were encountered with the user details and such. Such an approach is convenient if you have multiple optional data that depends on previous choices.
Of course you could also enter the data in one single form and send it to the server via a POST request and then create the respective resources that way. Which URL to return in the Location header is yet a different decision. If the main resource being created is the organization that I'd opt for the organization URI, especially if it allows to list its defined users. Internally you can utilize transactions to guarantee a consistent state between organization and user and in a failure to do this you simply can roll back the transaction and return an error to the user.
If you attempt to divide the creation into multiple steps you surely will have to deal with the exception case of the user resources and its effects on the organization resource. As mentioned HTTP does not give any hints on that as to HTTP these are two separate and unrelated requests. Here, not the server should be the smart thing but the client has to be. If it encounters problems while user creation it should perform the cleanup of the organization itself. The server/API is just seen as dumb storage thing in such a case.
How to handle the authorization after creating the organization? Can everybody with the organization id simply create a new user without any login check (login is only possible with email and password)? Or will the create organization return a token to create the first user? (The token logic will make the client quite complicated: how to handle resubmissions etc.)
It basically depends on your design here. Usually some kind of permission management should be added to the API. Some frameworks already contain support for such, i.e. in the Java and Spring ecosystem you can add certain annotations onto operation endpoints and business methods that check certain assigned user roles and permissions and only allow access if they are available.
In case you have a split organization and user creation approach and encountered a problem during user creation you could send a form back to the client requesting other user details as one already exist for an other organization until valid data was returned. Plenty of Web-based APIs nowadys send some confirmation links via mail to verify the correctness of the email-address and the user is only "logged-in" the first time when he clicked the activation link in that email. In pure HTTP you'd send a HTTP Authorization header containing the user credentials. In the absence of an activated user the service would return 401 Unauthorized as failure preventing the user from authenticating with the service. In such a case an external administrative entity (i.e. a project manager or administrator of the API) would have to create a user for that organization and send the data to the requestor. Though, such a state should be highly avoided IMO. Here, probing a user for admissible user details is sure preferrable, I guess.
You might also run some kind of cleanup routine in the back (or perform a manual cleanup task) after a given threshold amount on organizations that have no user assigned to it to free up resources and avoid carrying arround inconsitent state, according to your definition, as there has to be a user assigned to an organization.
As you see, you have a couple of design choices how to tackle such a scenario. Whether you enter the data in one form and send everything in one go to the server or use a temporary resource to collect data from n consecutive form requests until the user confirms that data and you process everything in one go atomically or you use dedicated requests per task and have some backing routines that check the consitency of the system is up to you.
A final note on a thing mentioned in your title. REST clients shouldn't consider resources to have a specific type as this leads to clients expecting certain endpoints to return certain types. This also leads to clients interpreting URIs to determine the type of that resource. As the server is free to change its URI scheme any time it wants to, chances are that clients wont be able to determine the type based on the URI automatically without a developer building in that kind of knowledge into the client. This avoids the actual benefits a REST architecture should provide, namely the freedom for evolution in future that is enabled by the decoupling of clients from servers. Instead of using typed resources clients should rely on content-type negotiation where standardized representation formats understood and supported by both, client and server, are exchanged. The media-types defining these representation formats specify the processing rules and semantics of each of the elements within the payload and allow interoperability.

Designing a SaaS on a single database, multi-tenant (SQL)

I'm working on a SaaS product and trying to figure out the best way to design the database for my scenario, which I think is pretty standard.
I should not that I don't have an experience designing such a database.
I tired researched online, but there isn't really any info I could find about implementation. There are quite a few comparing the different multi-tenant architectures.
For the multi-tenant approach, I decided go with a single database - seemed to be the most fitting.
Here's the basic list of what should be supported:
Multiple clients, all separated, no sharing of data between them.
Each client has it's own user base (staff/employees).
The client's staff members have different access levels to the system (exposure to different areas, ability to perform certain actions)
Each client have it's own customers.
I can wrap my head around the basic concept of having the tenant_id on any table belongs to that tenant. I guess my issue is more with how to combine it with different access levels per client's staff member.
How would you go about it?
Any reference some implementation of such a DB?
Thanks
Update
After #dmfy answer, I gave it some thought and came up with this solution:
account
-id
-name
user
-id
-account_id
-username
-password
role
-id
-account_id
-name
user_role
-user_id
-role_id
access
-id
-role_id
-name
role_access
-role_id
-access_id
session
-account_id
-user_id
-token
I'll explain-
The role table is essentially a "group" of users associated with a list of permissions/access levels.
The access table represents a single permission. An area of the platform, an action that can (or cannot) be performed.
A row in the session table is created after a successful login. Each time there's a call to the server, if the user has been verified against the token, I will lookup the roles for that user (using the session.user_id on the user_roles and collect it's access list using role.id on role_access.role_id).
Once I have the access list I can check against the request and see if the user is permitted to perform the action.
Notes
role can be customized for each tenant/account (e.g one can have "Management" and "Employees" and another can have "Management", "Support", and "Sales" ), hence the association with account.
access on the other hand, is platform-wide. The platform have the same set of areas and actions across all tenants. So there is not need to associate it with a specific account.
An improvement to the access lookup could be to store the access list on the session on login, to eliminate the double join (get all the user's roles, get all the roles' access lists).
Questions
Firstly, what is your overall opinion on the design. Do you see any flaws?
Is saving the account_id on the session really needed/a good idea?
Is having the server check whether the user has access to a certain resource is the standard way of doing this? Is there a way to do this as part of the itself query (e.g get an error from the DB itself)?
You might get a better answer by describing the requirements before you outline the solution.
Your design seems to describe an authorisation scheme. It looks fairly credible - I'd summarize it in natural language as:
A tenant is an account.
An account has many users.
A user can have
many roles.
Roles grant access to many permissions.
The system
maintains a list of sessions, mapping requests to users; this in turn
allows the system to check whether the user has permissions for a
given action.
Without knowing your requirements, that seems fairly reasonable. You may want to include a link from "account" to something your application recognizes as "tenant".
The big question is how you will use this data in your application. Checking permissions - especially fine-grained permissions - for each request could be expensive.
The specific solution here depends heavily on your application framework - many have built-in authentication/authorization models, and it's usually a good idea to use those built-in features.
For ideas on how to implement this, you could look at CanCanCan, an authorization framework for Ruby on Rails, or Authority for Laravel.
It's also not clear how the actual data in your system will be linked to an account - if your system tracks widgets, does the "widgets" table have an "account_id" column? If so, how does your application track who is and is not allowed to access that row?
It sounds like you're conflating database users with application users. In a SaaS product with a shared-schema model, individual users won't have direct acess to the database; instead, your application connects as a single user with appropriate rights on all objects it needs. What you're worried about is what areas of the application users can access and what actions they can take. This means you need to build your authorization model into your schema.
The simplest possible model has two levels of access: regular users and administrators. This can be represented with a users table having a tenant_id to associate individual logins with the correct client, and an is_admin flag. Your application then ensures that only users with the flag set can access administrative functionality. If your authorization model is more complex, design your schema appropriately (users may have a many:many relationship with roles, for example).
Note also that a tenant_id column is only strictly required for tables directly related to tenants; if you have a profiles table with a user_id, you can trace the relationship back to the tenant through users. In some cases it may make sense to add the tenant_id to avoid long join chains.

Orion Context Broker - references to data models

I'm preparing laboratory script for presenting features of of OCB, however
there is a misconception on how OCB references to Data Models defined by
FIWARE. I'm aware of parameter 'type', which is supplied along with new
entity. The problem is connected to OCB. How does it difference between data models?
I can add variables from different data model which don't match. I
can't find the controller for it and if there is no any that's really shame. The problem I got is connected with situation:
Creating entity with declared type for instance: Device
Adding some parameter, which is not specified in Device schema. It could be dateLastWatering from Garden data model.
It doesn't make any sense, how the OCB reacts to that?
From my experience it just "swallows" the updated content as long as semantic of command is correct.
I received information that a restriction can be implemented in application layer, however in my opinion it should be supplied along with OCB already.
That way model can be mistaken and the example is not really educational. It
could be useful if after defining a model for entity, OCB could interact
somehow with user and check, or debug what it receives. That way it would be
more professional I guess and fore sure more safe to use. If OCB doesn't have
that feature is there a possibility for further development?
Orion Broker is totally agnostic with regards to Data Models. Orion is not intended to check schemas or perform data validation. In fact, it is a nice feature that the schema of the Data is free and up to applications.
However, FIWARE defines Data Models to promote harmonization in certain domains, for instance smart cities. So it is nice to reuse or extend existing data models for the sake of data portability.

Options to remove or modify AspNet Identity

I am developing asp.net mvc web application with Entity Framework 6.1.3.
The asp.net identity that comes by default seemed fine to me until my boss said we cannot make any changes to the database tables (users, user roles) to fit with aspnet identity, as it is a legacy db..as is described here: https://www.youtube.com/watch?v=elfqejow5hM
So, what are my options now?
can i totally remove aspnet identity? how?
can i tell my identitycontext that my table names and columns are different and also change the behaviour in rolemanager?
On top of all this, my database is a mysql db Cheers :)
A default ASP.NET MVC project with Individual User Accounts, comes with a middleware named Owin, which in short allows a lot of authentication configs for your app, like:
Cookies Authentication
Cookies External Auth
Two Factor SignIn (e.g a password + code in mobile by sms)
Facebook Authentication
OAuth Bearer Token
etc...
Meanwhile, Identity is a library built to mix various old memberships, thus allowing you to work with many ASP.NET frameworks, such as ASP.NET MVC, WebForms, etc. Moreover, it comes with a built-in implementation, which also works as a provider for owin capabilities. Though, Identity is all based on interfaces, so developers can easily customize anything there, like plugging/unplugging features. This is just a short description.
So, what are my options now?
Use Identity's built-in engine, it'll create new tables for itself (including AspNetUsers and AspNetRoles), which you won't mix with your existing tables. Inside Models folder, there is an IdentityModels.cs file, with an ApplicationDbContext class, inheriting IdentityDbContext. Bring your existing DbSet for your models there (including for the existing user and role). You can create a relationship between the ApplicationUser (which comes by default with a brand new project, representing an IdentityUser) and your existing User. So you won't affect your existing tables at all.
You can implement all Identity's interfaces by your own (not that hard, but it takes some time to understand), then you could make your existing User and Role implement respectively IUser and IRole to combine with Identity.
You can make your existing models for User and Role just inherit IdentityUser and IdentityRole. After this, naturally your ApplicationDbContext would like to insert/update some columns in your tables to fit IdentityUser and IdentityRole models (since your classes now inherit from them), then you might want to configure it to avoid changing your existing tables.
Can i totally remove aspnet identity?
Sure you can. If you don't need all that Owin's features at all, you might not even use it, for sake of simplicity.
How?
You could just create a new project with Forms Authentication rather than Individual User Accounts, and implement a custom RoleProvider to interact with your existing Role. It's kinda easy to implement a custom RoleProvider for forms authentication. You can make your provider check for roles by querying your tables, or consuming a webservice, it's up to you.
Can i tell my identitycontext that my table names and columns are
different and also change the behaviour in rolemanager?
Sure. Override the OnModelCreating method in your ApplicationDbContext (the same one which inherits IdentityDbContext) to change all its default behaviour when generating/updating database. You might not call base.OnModelCreating(modelBuilder);, because this is what creates a lot of configs for your tables.
I suggest you to start reading about ASP.NET Identity and maybe Using MySQL Storage with an MySQL EF Provider, so you can decide whether you keep Identity, customize it, remove it, etc.

MySQL and MongoDB used on grails webapp together.

I have a User domain class that contains Profile domain class for the user. I need to use MongoDB for the Profile domain class in order to perform certain document search queries. Currently I have an instance of Profile in the User domain class as User has Profile, or Profile belongs to User.
I was wondering if such approach is going to cause problem down the road. Meaning that I have two domain classes which are pulling data from two different data sources.