Rails 4 generic parent model with more specific child models - ruby-on-rails-4

I am working on my first real Rails 4 app and I have run into a problem with my design.
Currently I have a "Service" model which started out with attributes such as name, online_status, ip, dns_name, port, and service_type. This model has evolved to include many methods and attributes for specific service_types (like auth_tokens, etc.) and thus it is very overgrown. The columns added to the database to accommodate the needs of the different types of services make this model act like a ghetto version of STI without separate classes/models.
The Service model also has methods such as ping() which is used to determine the online_status. I believe the types of services are different enough to warrant their own separate tables because each service seems to have many unique properties and methods.
Example:
A generic service has: name, ip, dns_name, online_status, etc...
A specific service such as Plex will have: name, ip, dns_name, online_status, username, password, auth_token, etc...
The issue, is that I would like to be able to access the more specific types of services from their parent Service class. So when I create a view, I can loop through all the generic services and the more specific services as if they were all the same type of service (or at least be able to access all services in some simple way without looping through each type and appending them).
I also need to access the specific types of models on their own, so doing something like #couchpotatos.each in my view will only go through the instances of the Couchpotato class.
Controllers play into this confusion too since I don't exactly know how to have a single page display all these different types of models from the same controller.
Criticism is welcome! I'm learning, so if this desired design absolutely bonkers, please let me know :D

Ok let's give it shot. I hope I understand your current situation, but the first thing a thought of is using a ServiceConcern containing the shared logic of a service. So a basic example would be:
module Service
extend ActiveSupport::Concern
included do
belongs_to :user
end
def ping
"pong"
end
end
class PlexService < ActiveRecord::Base
include Service
def ping
"plex-pong"
end
end
You would create a new model for each Service implementation that MUST have the stuff a Service should have (in the case above it would be a user_id)
The problem remaining would be a generic way to find all the implementations of the Service concern.
To achieve that, you have to implement a STI, where the Base object would be "Service" with user_id and a type (in the case described above) and implementations with their overrides

Related

Retrieve db records based on user role

I'm new in Laravel that's why I'm pretty sure that my ideas are wrong. To the point...
I'm building Laravel application.
What I have among other:
Users ( build in with Laravel auth with my custom fields )
Roles ( pivot, many to many )
Companies ( each user belongs to company ( many users can belong to one company ).
Locations ( each company has many Locations )
Now I'm in the middle of creating documents. For now it doesn't matter if user_id or company_id will be included in the document header.
What I need is to have ability to e.g.
Show documents - when I go to page with documents list with ADMIN role I will see all docs stored in db BUT when user with USER role goes to the same route ... he'll get the list of owned docs
location/edit/{id} - prevent going to url with not mine id - this is simpler and I guess can be dealed using middleware
I have 3 ideas:
Create somekind of FrontController and inside constructor run method that returns all users_ids ( or all companies_ids ) if user is ADMIN or when USER return only one id. All controller in the application then extends this FrontController
Create Service Class ( end up with many services depends on what model to retrieve ), method to get records from db calling repository with role parameter. Then in this method do the checks which ids should be used.
Maybe User somehow Laravel Policies and before() method. Nów I’m reading documentation but I really don't know how to use it in this case but I feel that this idea is also possible.
I feel that these ideas are "dirty". Can you, please, provide information how to implement this nicely with code snippet? I think this subject is very common and a lot of people will use this thred. I would be grateful for any tips.
One approach could be using local scopes.
https://laravel.com/docs/5.5/eloquent#local-scopes
On your Document model define two scopes:
public function scopeBelongingToUser($query)
{
return $query->where('user_id', auth()->user()->id);
}
// this is the same as doing on your User model
public function documents()
{
$this->hasMany(Document::class);
}
public function scopeBelongingToAdmin($query)
{
if (auth()->user()->roles->contains('admin') {
return $query->select('*');
}
abort(403, 'Unauthorized');
}
Then you can use it later with:
Document::belongingToUser();
Document::belongingToAdmin();

Check if user has a permission with specific codename in django

I am trying to check if a user has a permission, which I have defined in the class Meta of the model, with a specific codename. At the moment I have:
if request.user.has_perm('app_label.code_name'):
do something
What I am trying to avoid is using the app_label, however using has_perm('code_name') does not seem to work.
The way this function works is that you need to pass the app_label, so not much you can do there.
One workaround can be to write your own wrapper function, something like:
def _has_perm(user, code_name, app_label="app_label"):
return user.has_perm(app_label + "." + code_name)
The reason you need to provide the app label is that permissions are application specific. That means if you have two apps, app_a and app_b, both with a model named Farm, they could both have a permission called can_create_new_chickens. It is very important to understand that there are two separate permissions here:
app_a.farm.can_create_new_chickens
app_b.farm.can_create_new_chickens
These are independent permissions, and a user can have neither, both or one or the other. This means it would be insecure to validate permissions without referring to the application name. Permissions given to a user in one application could affect their permissions in another application.
Back to your question, the answer is no, you cannot check permissions without the application name for the reasons given above.

Apigility: I don't use hydrators. Is Apigility still a good fit?

I am investigating Apigility as a way to add REST services to my ZF2 application however I see that it uses hydrators. My domain objects are created by factories which validate and filter data, add proxies, etc, then instantiate and return an object of the required type. The factory injects the domain object data via the constructor.
It seems to me that I need to change the workflow for how Apigility creates domain objects. In my case it will need to instantiate a factory and feed the inputs to it. Does this sound right? Where do I start?
I think this should not be a problem.
You can inject your resource factories inside your resource listener instance. Inside the methods of your listener (create, update, etc) you can use your factory to do its job (for example create a resource) and then you return a Hal\Entity or Hal\Collection as a result.
Hydrators are mostly used inside the Hal plugin for extracting data while rendering your (nested) resources. In case case you return a Hal\Entity or Hal\Collection instance directly from your listeners the plugin won't be needing any hydrators. The only condition is that the content of your Hal resources is json serializable (so no complex objects).

How to deal with deep level granularization with XACML in enterprise application

I am using IS WSO2 for authorization with XACML. I am am able to achieve authorization for static resource. But I am not sure with the design when it comes to granularization.
Example : if I have method like getCarDetails(Object User) where I should get only those cars which are assigned to this particular user, then how to deal this with XACMl?
Wso2 provides support for PIP where we can use custom classes which can fetch data from database. But I am not sure if we should either make copy of original database at PDP side or give the original database to PIP to get updated with live data.
Because Cars would be dynamic for the application eg. currently 10 cars assigned to user Alice. suddenly supervisor add 20 more car in his list which will be in application level database. Then how these other 20 cars will be automatically assigned in policy at PDP level until it also have this latest information.
I may making some mistake in understanding. But I am not sure how to deal with this as in whole application we can have lots of this kind of complex scenario where some times we will get data for one user from more than 4 or 5 tables then how to handle that scenario?
Your question is a great and the answer will highlight the key benefits of XACML and externalized authorization as a whole.
In XACML, you define generic, global rules, about what is allowed and what isn't using what I would call high-level attributes e.g. attributes of the vehicle (in your case) or the user (role, department, ...)
For instance a simple rule could be (using the ALFA syntax):
policy viewCars{
target clause actionId=="view" and resourceType=="car"
apply firstApplicable
rule allowSameRegion{
permit
condition user.region==car.region
}
}
Both the user's region and the car's region are maintained inside the application's database. The values are read using a PIP or Policy Information Point (details here).
In your example, you talk about direct assignment, i.e. a user has been directly assigned to a vehicle. In that case, the rule would become:
policy viewCars{
target clause actionId=="view" and resourceType=="car"
apply firstApplicable
rule allowAssignedVehicle{
permit
condition user.employeeId==car.assignedUser
}
}
This means that the assigned user information must be kept somewhere, in the application database, a CSV file, a web service, or another source of information. It means that from a management perspective, an administrator would add / remove vehicles from a user's assigned list (or perhaps the other way around: add / remove assigned users from a vehicle's assigned user list).
The XACML rule itself will not change. If the supervisor adds 20 more cars to the employee's list (maintained in the application-level database), then the PDP will be able to use that information via the PIP and access will be granted or denied accordingly.
The key benefit of XACML is that you could add a second rule that would state a supervisor can see the cars he/she is assigned to (the normal rule) as well as the cars assigned to his/her subordinates (a new proxy-delegate rule).
This diagram, taken from the Axiomatics blog, summarizes the XACML flow:
HTH, let me know if you have further questions. You can download ALFA here and you can watch tutorials here.

Kohana 3.1 Web Services Bootstrapping Based on Environment and Stored Like A Session

We are building a n-tiered style application in Kohana 3.1 which distributes JSONP powered widgets to our partners based on a partner_id.
Each partner needs to be able to call a widget and specify an environment parameter: test OR production with the initial call, which will be used to select the appropriate database.
We need our bootstrap to watch for $_REQUEST['environment'] variable and then to maintain the state of that variable whenever the partner makes a call to the widget service.
The problem is, that all requests in the application use Bootstrap.php, but many of the requests are internal - i.e. they do not come with a partner_id or environment variable. We tried to use sessions to store these, but as these are server-to-server GET/POST calls, it does not seem possible to store and recall the session id in a cookie on the server (this is browser-less GET).
Does anyone have any suggestions? We realise we could pass the environment variable with every single call internal or external, but this does not seem very robust.
We have a config file which stores partner settings (indexed by partner_id), such as the width and height of the widget and we thought about storing the partner's environment in here, but not all calls to the server would be made by a partner, so we would still need another way to trigger the environment for other calls and select the correct DB.
We also thought of storing a flat file for the partner which maintains the last requested environment, but again, as we have many internal requests after the initial one, we don't always have a knowledge (i.e. we don't usually care) which partner_id is used in the initial call.
Hope this makes sense...!
The solution would be to call the models and methods that are needed to 'do stuff' from a single controller, keeping the partner_id only in the controller and sending the requested data back once all of the 'do stuff' methods have been run, as per the MVC model.
i.e., request from partner -> route -> controller -> calls models etc -> passes back to controller -> returns view to partner
That allows the partner_id to be kept by the controller and only passed to whatever models require it to 'do stuff', keeping within the MVC framework.
If you've not kept within the confines of MVC, then things will obviously get more complex and you'll need to store the variable somewhere.