I have a two repositories Catalog and User, I have a situation where I need to call a method within the catalog repo from the user repo, is this good practice or is there a better way?
You shouldn't be handling those kind of authorization checks within your Repositories. A business rule like "This user requires X comments to post" isn't really a repository query, it's a property of your User.
Also, authorization calls are made very frequently in an application, and you really don't want to hit your database every time a check is required.
You should properly load these permissions into your User object which is then cached for the current request, and use your domain:
public class Service {
public void Save(Post post)
{
if(User.GetCurrentUser().HasEnoughCommentsToPost())
postRepository.Add(post);
}
}
I would reference the other Repository at the upper layer, such as a service layer
I think that in your case authorization is part of your domain logic. So I'd create an abstract class or interface called AuthorizationPolicy (maybe you can find a better name closer to your domain), in my domain layer. Before you call a method on the repository, the client should check if the have have permission based on the policy.
Another solution, because the interface of a repository is also part of the business logic, you can create a base class for your repository which check permissions of the user and delegate the rest to derived classes.
The implementation of the AuthorizationPolicy will talk to the Catalog class if you want. This way the two repositories are well decoupled.
Related
How to implement multiple authentication with one model named User? There are different roles attached to this model. I need to implement multiple authentication as user and administrator.
Better not to call it “multi authentication”. Multi authentication is a completely different conecpt. Basically you will have to have 2 guards setup.
But if you are using one single guard (user guard in this case) you will have to simply assign roles by creating a new column in users model called “roles” or what ever you prefer.
After you have setup the roles colum in your users model, create a middleware and configure the rest. Explanation:
In your “role” middleware or whatever you prefer, specify what roles are which and who has access to where. And include that middleware inside your controller in use.
If you stil want to have a multi authentication like one login and redirect separately for users and administrators, I’d suggest you to look at “the dev marketer” multi auth tutorial. It is a well explained and all the source code can be found in whole on github.
Keep in mind that the laravels default /login route is meant for normal user login (atleast for me). You can create a /admin/login route with the above mentioned tutorial.
Hope this helps. Good luck :)
Suppose that we have difference SMS provider for each tenant (each tenant have their own SMS provider that wants to send SMS thorough those provider) How can we implement this situation in ASPNetBoilerplate?
If each tenant has only one sms provider then you can create a complex type on Tenant class. If each tenant has more than one sms provider then create TenantSmsProvider entity.
I did not understand why you want to create DLL!
I suppose you are asking for the Dependency Injection.
You should create a factory (say ISmsProviderFactory) that creates sms provider (say ISmsProvider) by tenant id (say GetProviderByTenantId(int tenantId). This is a common software pattern. Then you can inject ISmsProviderFactory and get ISmsProviderFactory based on a tenant whenever you need.
Instead of creating a custom factory class, you can use Castle Windsor's API to register dependencies by factory. Thus you can directly inject ISmsProvider in your code.
Now, the problem is how to implement SmsProviderFactory? There are different approaches depends on your requirement. But this part is out of scope of ABP and you can find many articles on the web.
BTW, if you want to take advantage of ABP's plugin system, then you can design it a bit different: Every plugin dll can add an ISmsProvider to a dictionary (where the key of dictionary is tenant id / name) so your factory can pick registered provider for given tenant.
I wanna build a simple ember app with sails as the backend.
There are nice blueprints that will help me with that, but I want all data to be complete user isolated. So its actually a single user application, but for multiple users.
So all data is different for each user. So when ember makes a request to /notes/findAll I only wanna return the notes corresponding to the user. On the other side a user has full rights on all data that belongs to him (except maybe the user model, which is the only special case).
What is the simplest way to do this?
I could modify the blueprints itself! But is this a good idea? It would be nice to be able to combine it later by configuration on a per-model-base.
Is there a way to do this with a policy? So a policy setting a safe user-filter?
Is there another better/default way to solve my problem?
Thanks!
I am building the same sort of application. I accomplish this by adding an owner attribute to every model, and setting it in a policy.
https://github.com/tjwebb/xtuple-api/blob/master/api/models/base/xTupleObject.js#L29-L32
I created Permission and Role models, and if the object the user is asking for relates to their User object via a Permission and Role, then they are authorized for a particular action.
https://github.com/tjwebb/xtuple-api/blob/master/api/policies/authorize.js#L51-L56
If you want to grant access to the findAll method, you might want to re-implement it in a superclass that all your controllers inherit from. I haven't gotten to this part yet, but this is my plan for solving this problem.
I'm trying to design a good RESTful API for my web app and am looking at Facebook's Graph API as an example.
My plan is to dogfood the API in the web app. For example, if the user changes their name, gender, etc., on the settings page, it would just PUT to the /user endpoint of my web app with the new data.
However, I noticed that Facebook's Graph API does not allow modifications to the User resource. Are there some resources that you want to make sure are not modifiable from the public API?
I'm basically just wondering if there are any risks with my method, and if not, why other websites don't do the same thing.
Yes, there are resources that you want to prevent API users from modifying, but they are application dependent. For instance, an API I'm working on right now lets callers read but not update audit data, read user records (but only modify parts of their own), and create and update home addresses.
You will want to make sure that you have rigorous security in place to prevent users from modifying certain parts of a User (such as username or password), especially if user A is calling PUT /users/B.
I feel like exposing an edmx class as a parameter to a web service is not a good idea. I feel like it's wrong design. eg.
[WebMethod]
MyWebservice(int customerID, UserProfile profile){
}
now UserProfile is a class generated by Edmx framework. You might argue if the profile object is an input then it will not get a proper id (edmx id) because it will be created out of the context (since the web service can be called from any external consumer).
But i'm also looking for more explanation why exposing edmx class as a web service is not a good design. If you think it's ok, please tell me.
thanks
It's generally considered good design practice to keep the data contracts of a web service and the data model objects associated with a database separate, so that if required you could change the entity model used at the back of a web service, without having to change the interface that you expose to consumers of the service.