Django - social like permissions for objects - python

I'm learning Django framework and I'm trying to implement some social features / permissions for objects. What is the best solutions for such thing eg.:
We have some model (eg.: photo):
name_field
picture_field
owner_field
allowed_group_users_field
allowed_group_users_field <----- field where we will put gorup / users whose are able to see photo.
Now view which will handle showing pictures should use: "#user_passes_test" decorator which will check if requesting user is included in allowed_group_users_field.
And my question is:
Is it correct way to solve such thing or there are better solutions for that - maybe other decorator is more suitable or other way of implementation..?

Hello and welcome onboard!
I have a relatively new account also in stackoverflow but I have quite some experience with django.
The way i see it, you want to create groups like foreign keys one to many, to users who are allowed to see this.
Your solution with a decorator is pretty common and there is nice documentation here, https://docs.djangoproject.com/en/1.4/topics/auth/#limiting-access-to-logged-in-users-that-pass-a-test and an example for the kind of group you need, here https://djangosnippets.org/snippets/1703/.
So, all you have to do is to extend the current decorator with your own logic (if user belongs to specific group) and it will work.
I hope i answer your question!

Related

Django: Get notified of all changes in database

I was wandering if there's a way to get notified of any changes to objects in a Django database. Right now I just need an email if anybody adds or changes anything but it would be best if I could hook a function triggered by any change and could decide what to do.
Is there an easy way to do it in Django?
Two ideas come to mind:
Override the predefined model method for saving.
Use a signal like post_save.
Here is a good article that talks about the difference between the two things listed above and when to use them:
Django signals vs. custom save()-method
The article was written near the end of 2007, three days after the release of Django 0.96.1. However, I believe the advice the author gives still applies today.

Is Django's update_object generic view secure? Should I extend it or make my own for security?

I'm new to Django. Last night I worked hard on a view that would allow me to edit any of the entities in my current project; Chapters, Stories, and Worlds. In order to ensure that I know precisely which database object is being modified, I added a database entry to the tables 'edits' that stores the hash, the type of object being edited (eg. 'Chapter'), and the id of that object as found in the database. The hash is added to the form as a hidden input.
On the back-end, after the form has been submitted, I grab the hash and use it to find the related Edit item in the database. I then use this to find which object was initially being edited. This was done for two reasons:
I can know what object is truly being edited. If all form items have changed, there would be nothing to compare to (except URLs) to actually know which object is being edited.
Users should be unable to hack the front-end to do weird things like modify the wrong stories.
Today I discovered that Django has a generic view called update_object. This seems to handle a lot of things for me. But given that it doesn't automatically use the database to ensure that the correct object is being edited, or even determine which object is being edited, is this secure? surely there must be a simple way to hack it on the front end by modifying HTML elements.
Secondly, if this should be a concern, would you recommend that I keep my own edit view, or that I extend the update_object view, or some other solution?
Lastly, am I going about this the right way at all? Please correct me if I'm not thinking about solutions to this problem in the right way.
I don't feel that this is a question that requires code. It's more of a general question about the security of forms as they pertain to Django.
Thanks,
ParagonRG
Your problem of knowing which object they're editing is typically solved either by inspecting the URL or by a hidden form element that just has the database ID.
Before accepting any changes from a user form, you should be verifying that the user has permission to do whatever it is they're asking to be doing, and that the edits make sense. You'd normally do this with form validators and/or explicit checks in the view. This is a somewhat safer way of dealing with this problem, because it guarantees people aren't making DB changes they're not allowed to be making, whereas in your Edit object approach it's conceivable they could get around that.
If you take this approach, I don't see any reason why it's a problem that the user could be editing hidden ID fields to pretend to be editing a different object. They're just using a silly roundabout way to edit things when they could have just gone to a different edit link.
(Also: if you're using Django 1.3+, it's better to use the new class-based UpdateView rather than the function-based update_object.)

Trac - How do I access Custom Ticket Fields in ITicketChangeListener?

I'm trying to write my own Trac plugin to notify an external system of changes to tickets matching a certain criteria. From my research so far, I've figured out that implementing the ITicketChangeListener interface is the way to go.
The method definitions are all very straight forward, but what's not straight forward for me is the Ticket object and accessing its custom fields. I've learned that you can access default ticket fields as simply as:
# t is a Ticket object
theStatus = t['status']
I've found several sources that say this won't work:
myCustomField = t['my_custom_field']
Yet none of them tell me what will work.
In addition, I need to know if the old_values argument of the ticket_changed() method will have my custom fields or if I'll have to do something different there as well.
I'm fairly new to Python and very new to Trac. Any help to point me in the right direction is appreciated.
The sources are wrong about custom ticket fields. The value-by-name approach should work. And *old_values* contains all fields values, including custom fields too. That's it.
You may want to look at the TracAnnouncer source for some change-listener coding examples.

django application with multiple sites - how to restrict access for staff

I made a django application recently with multiple settings files, each setting file has its own SITE_ID and each SITE_ID is associated with site_id from the django_site table. Now, I want to create staff for certain sites only and other admins for all sites, how would I do something like that?
best wishes,
Mo - not sure whether you're still looking for an answer for this but this cross-post could be along the lines of what you're looking for.
I'm afraid I have bad news for you, you'll have to implement it on your own. What can
you do is to implement a new class say SiteUsers, it can look as follows:
class SiteUsers(models.Model):
site = models.ForeignKey(Site)
users = models.ForeignKey(User)
then you can use a kind of user_passes_test decorator to force access control. I'm not aware
of any ready to use solution.
another option would be to use groups. create set of groups for each site and sort users
to those groups. I think you'll have to have groups like:
site_1_add, site_1_delete, site_1_....
site_2_add, site_2_delete, site_2_....
however I'm afraid it does not scale so well. you will not find out unless you'll try.
anyway going either way will require a lot of admin customization. I really would need to do some research myself first.

Fully customized login system in Django?

I am currently writing an application which I plan to sell as SaaS. Without giving away "secrets," I can say that it is basically a "document editing system" in which many users will be submitting documents.
The basic heirarchy is this:
Institution
Individual
Document
Sub-document
So each Individual should be able to BROWSE all documents that were submitted by anybody in their institution, but should only be able to EDIT documents that they created.
No individual should even be aware of the existence of another Institution--that should all be completely hidden.
I have written a Django/Python class that would facilitate this, but every document regarding authentication that I have read requires that I use the User object. Is this just a limitation of Django, or is there a way to do this?
If there is a way, how can I get my own "Individual" class details attached to the "request" objects so I can validate the things I should be showing the users?
What you're looking for is authorization, not authentication. Django's built-in authorization system is fairly crude, as you've discovered. You'll need something like django-authority if you want a more complete solution.
The auth module is typically used to cover authentication cases.
Gives you groups (Institutions), Users (Individuals) and permissions.
Using these features you can perform checking if a user is a member of a group or owns a doc before allowing them to see or edit the doc.
http://docs.djangoproject.com/en/dev/topics/auth/
If you need to go beyond the typical use case, supporting LDAP for example, then you can look at writing your own authentication backend.
http://docs.djangoproject.com/en/dev/topics/auth/#other-authentication-sources
In general, if you need to attach more information to the builtin User model, you would create new model which subclasses models.Model (not User), and identify it in settings as AUTH_PROFILE_MODULE. You can get the appropriate instance of your model from a user by calling user.get_profile(). (see http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users).
This is generally useful for adding extra fields to User such as address, contact information, etc. While it would be possible to use this for your authentication needs, you'd most likely be better off using the built in groups, or a more comprehensive solution like django-authority as others have mentioned. I've included this answer only because it seems to be what you were asking for (a way to attach a class to User), but not really what you need (authorization).

Categories

Resources