In Tastypie is there a way to change a resources excludes based on the authentication? - tastypie

Consider the example of a user resource that has profile pic and email fields. Where any user may see any other users profile pic but a user may only see their own email address.
Is it possible to setup tastypie so that the set of excluded fields can be varied based on the authenticated user?
I realize that an alternative approach is to create separate full and restricted user resources. But for the moment I just want to know whether the approach of limiting the fields based on user authentication is even doable in tastypie.
Also it doesn't have to be the excludes, in the same vein is there a way instead to change the fields property based on the requesting user?

I dont think excluded fields can be brought back into the picture in an elegant fashion. You could probably manipulate the object list based on the request using some object manipulation by including the get_object_list in your resource
But it would be much better and more logical for you to use the apply_limits method in your custom authorization class.

Yes there is a way to do it.
If you define email to be a separate field, not the one of the User(might work and with that but never did it).
You can define dehydrate_email where the bundle.request contains the current request and you could get it. It won't be exactly excluded as a field but it will be None for others.

I created a ModelResource subclass that can be multiple inherited into the required ModelResource instances. Like:
class ResourceThatNeedsToExcludeSomeFields(ExcludeResource, ModelResource):
pass
It takes in the fields to be excluded via GET parameters (like "&exclude=username")
class ExcludeResource(ModelResource):
"""
Generic class to implement exclusion of fields in all the ModelResource classes
All ModelResource classes will be muliple inherited by this class, whose dehydrate method has been overriden
"""
# STACK: How to exclude some fields from a resource list created by tastypie?
def dehydrate(self, bundle):
# I was taking the exclude fields from get paramaters as a comma separated value
if bundle.request.GET.get('exclude'):
exclude_fields = bundle.request.GET.get('exclude').split(',')
for field in exclude_fields:
if str(field) in bundle.data.keys():
del bundle.data[str(field)]
return bundle
You can modify this to get the exclude fields based on user group (or whatever criteria you base the fields on) like this:
class ExcludeResource(ModelResource):
"""
Generic class to implement exclusion of fields in all the ModelResource classes
All ModelResource classes will be muliple inherited by this class, whose dehydrate method has been overriden
"""
# STACK: How to exclude some fields from a resource list created by tastypie?
def dehydrate(self, bundle):
exclude_fields = <get a comma separated list of fields to be excluded based in bundle.request.user>
for field in exclude_fields:
if str(field) in bundle.data.keys():
del bundle.data[str(field)]
return bundle
However, this snippet will not work for related resources specified with "full=True"

Related

Yii2 adding parameters to the model with a function

I have two types of data. Articles and article types. They are stored a postgres DB. Every article instance should have particular type. All articles have common properties like "name", "create_date" and so on that are in every article and fields that are specific for the specific type like "some_image", "ingredients", and so on for the type1 and "images" and "points" for type2.
The additional properties for the specific type are stored in a single json column in the db table.
When the url "some_path/articles/create/2" is opened a form for creating an article of type 2 is displayed
I have an Articles ActiveRecord model and ArticlesController.
My problem is that in the model I have only have the common properties. And the additional properties are always different.
I need a method in the model or in the controller with which I can add the additional properties with the proper rules and all (like the common properties in the model) and then in the view I can render all fields without difference.
Is there a way this to be done and how?
I read how this can be done with Javascript, but I want it to be dobe before page rendering, not after that
May be this can help.
Use Scenario in your model
Model class has scenario function which you can inherit.
User Register Scenario - Required - username, password, email
User Login Scenario - Required - username, email
public function scenarios() {
$scenarios = parent::scenarios();
$scenarios['login'] = ['name','password'];//Scenario Values Only Accepted
return $scenarios;
}
and you can use it as

How can I post the custom field to Workfront through workfront REST API

In workfront, we want to create a custom form(custom fields) for an Issue. How can I use Workfront REST API to do a POST request and create the custom fields in a custom form for that issue in workfront?
https://developers.workfront.com/api-docs/api-explorer/
You POST the same as you would to a system field. Simply prefix the field name with DE:.
attask/api-internal//user/xxxxxxxxx?DE:foo=bar
The above sets the field 'foo' to the string 'bar'.
If the custom field is not present on the object (not on a custom form already attached) then you will first need to attach one.
attask/api-internal/user/xxxxxxxxxx?updates={objectCategories:[{categoryID:`"customformUUID`",categoryOrder:0,objCode:`"CTGY`"}]}

Realm Swift inverse relationships many-to-many

I'm currently trying to work out the best way to architect my realm objects for ease of retrieval.
I have 2 objects tags and object there are multiple tags and each one might contain many object. Similarly each object could have multiple tag associated with it
Ideally selecting a single tag should retrieve all object that have at least that one tag (but could obviously have multiple)
would my models be specified as
class Tag: Object {
let objects = List<Object>()
}
class Object {
let tags = List<Tag>()
}
I don't think I need to use an inverse relationship here or should I? Choosing a Category I should be able to just retrieve a list of all object references regardless, but then maintaining and updating the references to an object might be difficult here? I.e a user selects tag 'A' then updates the first object to also include tag 'B' I would need to update the object in the List for Tag A, then add a new item to the list for Tag 'B' and finally update the actual Object itself to include Tag 'B' in it's list of tags.
Just to be clear an Object will only ever display and allow editing of it's Tag objects. But the Tag object itself will need to know what Object's are applicable to it.
However it feels like I will have to do multiple updates when ideally I'd like to minimise this effort. Can anyone recommend a better way to do this? Or is there no way around this due to the limitations of Realm?
This is exactly what LinkingObjects is for. Changing the objects property in Tag to let objects = LinkingObjects(fromType: Object.self, property: "tags") will make it automatically update whenever a tag is added to an object.

How to use Entity, Mapper, Service and Hydrator in ZF2

I am making a ZF2 app. I am using entities, mappers and services (e.g. UserEntity, UserMapper, UserService) to manage the objects/models. Properties in the entities are CamalCased (e.g. FirstName, LastName) while in the database, fields are using underscore (first_name, last_name). I will plan to use a hydrator to map the properties and db-fields when retrieving or saving. The service object (UserService) will be used to communicate with the mapper to retrieve and save data models using the mapper. The hydrator will convert the result of mapper and convert them into proper entities.
The thing I am confused is that when the service (UserService) need to provide some cirteria - for example to find all users with a specific 'last name', will the service use the database field names (last_name) or entity properties name (LastName)?
If the db field name is used in the Service, so any change in the db structure will require me to update the service also, which completely fails the reason of using the whole approach.
If you take a look at the ClassMethods:hydrate method (https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/Hydrator/ClassMethods.php) you will see that it just copies the properties from one object to another. You have the option of converting the property names to/from camelCase but that's it.
If you change a column name in your database then you will need to change corresponding property name in your object. And vice versa. Which I believe is the crux of your question?
If you want to make table column names be independent of your method names then you need something that lets you define an actual mapping table somewhere. Change a column or method name and you only need to update the configuration mapping table.
Not a ZF2 expert so I could be wrong but it doesn't look like any of the supplied hydrators support this.
I do know that Doctrine 2 supports it.

Foreign entity in form into different kind of input

I have two entities: product and category (Symfony 2.3).
I want to create a form in which an user can choose a product by first selecting the category. A user selects the category by clicking on image, then I want to set the image's value into a hidden input, but I don't see how can I change a foreign entity choice list to a hidden input (http://symfony.com/doc/current/reference/forms/types/entity.html).
How can I accomplish this? (how to change form input to hidden)
If I set cascade validation to true, will it for example check if a category really exist. (To prevent putting products with non-existing category from malicious users) ?
Part 1
To do this you need to use a data transformer to do two things:
transform an entity into an identifier that is either a string or integer so a form can render it as a hidden field.
transform the string or integer identifier into the entity when the form is submitted so that the parent entity can be saved with the correct relationship
The symfony docs I linked to above (here too) actually walk though an entire example of using a data transformer with a form.
As a shameless plug (because I believe it is helpful) I have written a little tutorial on using a data transformer for a hidden field with an entity id: http://lrotherfield.com/blog/symfony2-forms-entity-as-hidden-field/
Part 2
If you are using the data transformer then you don't need to worry about malicious users. The data transformer will fail because it will not be able to reverse transform the category from the fake id. In my tutorial the transformer will throw a Symfony\Component\Form\Exception\TransformationFailedException exception.
You can also write a validator (potentially using a call back) if you wanted that checks that the submitted category is real if you want an error to show in the form. Doctrine wont allow you to persist a fake category relationship as the foreign key constraint will fail.