I have got an architectural question. Where should I check user permissions for certain operations?
For example:
1) In a controller, I get parameters from view and start a process in the intermediate model.
2) Intermediate model decide which parameter should be converted and transformed in any way and modify or create data through Models
3) Model communicate directly with DataBase
Where do You think is the right place in that "architecture" to check privileges to for example save sth to database?
I would actually put the authorization check before the controller is being called, kinda like described here (I really need to update that old post). Preferably as a decorator around the controller instance, which would give you a fine-grained control over what operation user is permitted to do, based on controller+method pair.
Another point where you might think about is "authorization lookup" helper function for use in your templates, because you might need to show or hide some UI elements from users, who should not be able to perform the associated operations. The controller+method check, before execution would still work as the actual safeguard then, but it tends to be a quality-of-life improvement.
You should not put the authorization checks inside the each controller or (even worse) model layer, because that tends to promote an excessive amount of copy-paste, which in turn can cause mistakes and becomes a huge problem, when you want to alter the mechanics of your authorization system.
Related
I am new to Django and want to know deeper about the concept of signals.
I know how it works but really don't understand when should one really use it.
From the doc it says 'They’re especially useful when many pieces of code may be interested in the same events.'
What are some real applications that use signals for its advantage?
e.x. I'm trying to make a phone verification after user signup. Because it can be integrated inside the single app and the event that interested for the signal is only this 'verify' function, therefore I don't really need signal. I can just pass the information from one view to the other, rather than using pre_save signal from the registration.
I'm sorry if my question is kind of basic. But I really want to know some insight what is the real application, in which many codes interested in one particular event and what are some trade off in my application.
Thanks!!
Often signals is used when you need to do some database-specific low-level stuff. For example, if you use ElasticSearch for better searching documents on your site, you may want to automatically update search indexes, when new document is created or old one was edited.
Also you may have some complex logic of managing database objects. For example, you may need some specific logic of deleting object. For example, when user is deleted, you may want change all the links to his profile by some placeholder, or when new message is created or other action is performed by user, you want to update "last visited" field in user's profile and there's no direct relation between this action and updating the profile.
But when you're just implementing business-logic as in your example with verification, you don't need to use signals, because you don't need any universal logic related to deleting/creating/editing any object: you have a certain object with which you work and can do stuff directly.
I have a question regarding some action accessing, i'm not talking here about authorization etc, but more about the direct access to actions.
Basically i have 2 question, 1 general and 1 more contextual:
Situation imaging i have an action : MyArticles/DeleteArticle/id
1) How can i prevent that if someone will just put this url with a proper id remove article? How can i say that it can only be used with a button on my website? And should this action be a get or post?
At this moment i use $.ajax and GET method ....
2) Now imagine i have many people, and if all th ppl are registered, they can delete each others article, what if i want to avoid that and let users only delete their own articles, because at this moment for example if they can guess the id they can directly access the action with id and delete it.
Can anyone provide explanation and some tips about that?
i'm not talking here about authorization etc
Yes, you are. The authorization to delete the article should take place within the action itself, it's not the responsibility of the calling code or of any UI which displays a link to the action.
How can i say that it can only be used with a button on my website?
I imagine any approach to that is going to complicate the issue tremendously. Understand how HTTP requests work... Your application isn't making the request to the action, the user is. They're doing so (in the general case) by clicking a link on an interface provided by your application, but the request itself is coming from the user. (Well, from the user's web browser, which is in their control and not yours.)
The most straightforward approach to this is to encapsulate authorization in the action itself (or, better still, in the model functionality being invoked by the action... but logically that's still part of the "request" being performed).
When you expose a piece of functionality which not everybody should be able to invoke, put the authorization on the functionality itself instead of on the UI which invokes it. That way no matter how it's invoked it always maintains the authorization, instead of just assuming that some other component maintained it.
You have a lot of control in MVC with respect to the USER. To allow a user to delete only his own work, you must remember in the database who wrote what. If this is the case - and you know it, a simple if statement in the beginning of the action will do the trick.
I'm an advanced beginner at django and python. I'm writing an app to handle registration and abstract submission for a conference, and I'm trying to use class-based views. Users get an emailed link that includes their registration code in the url. Starting at this url, users move through a series of views that collect all the necessary info.
The complication comes from the fact that users often stop half way through, and then want to complete the process several days or weeks later. This means that they might continue from the current page, or they might just click that original link. In addition, after several weeks they might have missed certain deadlines, so, e.g., they can no longer submit an abstract (but they can still register). Along the way, they have checked or unchecked various options that also influence the path they should take through the app.
My question is: where is the best place to put the logic that determines if the user is currently allowed to view that page, and if not, the best url to redirect them too? I thought I would create a custom view class that, e.g., overrides the dispatch method to include global checks (e.g., is conference registration open?), and then subclasses could add additional checks (e.g., has the user entered all the necessary info for her abstract?). The problem I ran into was that the checks were run in the wrong order (I want base class checks run first). I then started investigating custom view decorators or custom middleware. At this point I realized I could use some expert advice about which approach to take. (If it matters, I am not using the django authentication system.) Thanks in advance.
Maybe the form wizard could help you managing the viewing sequence.
In general django greybeards advocate keeping row-wise logic in Models, and table-wise logic in Managers, so it seems appropriate to keep complex view logic in a master view class.
The wizard class can help maintain the order of the views, but to resume an out-dated session you may need to do some model saves (which could get too complex very quickly) or some cookie handling.
In the past, when presented with a similar situation, I took the simplest route and separated user registration and the task that the user wants to perform (event registration). The user registers once but if they fluff up the event registration, they just have to log back in at a later date and do it again (their hassle - not yours!).
Should I be writing application logic in my view code? For example, on submission of a form element, I need to create a user and send him an activation email. Is this something to do from a view function, or should I create a separate function to make it easier to test down the road? What does Django recommend here?
I found it very hard to figure out where everything goes when I started using django. It really depends on the type of logic you are writing.
First start with the models: model-methods and managers are a good place to perform row-level logic and table level logic i.e. a model manager would be a good place to write code to get a list of categories that are associated with all blogposts. A model method is a good place to count the characters in a particular blogpost.
View level logic should deal with bringing it all together - taking the request, performing the necessary steps to get to the result you need (maybe using the model managers) and then getting it ready for the template.
If there is code that doesn't fit in else where, but has a logical structure you can simply write a module to perform that. Similarly if there are scraps of code that you don't think belong, keep a utils.py to hold them.
You shouldn't perform any logic really in your templates - instead use template tags if you have to. These are good for using reusable pieces of code that you you neither want in every request cycle nor one single request cycle - you might want them in a subset (i.e. displaying a list of categories while in the blog section of your website)
If you do want some logic to be performed in every request cycle, use either context processors or middleware. If you want some logic to be performed only in one single request cycle, the view is probably the place.
TLDR: Writing logic in your view is fine, but there are plenty of places that might be more appropriate
Separating the registration code into it's own function to make testing easier is a good reason. If you allowed admins to register users in a separate, private view, then a registration function would be more DRY. Personally, I don't think a little application logic in the code will do to much harm.
You might find it instructive to have a look at the registration view in the django-registration app -- just to see how it's written, I'm not saying you should or have to use it. It has encapsulated the user registration into it's own function (there's a level of indirection as well, because the registration backends are pluggable).
I have a C++ application designed according to a classic Model-View-Controller pattern. The model is modified through a controller interface by an external source by means of a Command pattern. The commands are represented by an Action object (and its derivatives).
Now I want to be able to undo the modifications, but my problem is that I have no getters in my controller, only setters. This seems quite logical, since there's no reason someone should be able to get info about the model through the controller. Thus, I can't have my Action objects store the state of the Model, since they have no access to it.
How would one solve this? I'd like to keep my application as extendable as possible and I'm not quite sure which option is the best for that. The methods I though up so far are:
Putting getter methods in the controller. This seems to go against the MVC pattern.
Giving the Action a pointer to a View. The Action could then either:
Use individual getters to get the state of specific elements of the model to be modified.
Use a Memento method implemented by the Viewer.
Maybe there's an even better way to do this? Right now, to be the best option seems to be 2, suboption 1 (with suboption 2, I'd quite possible store a lot more state than necessary to undo one action).
Note: I know there's other questions on how to implement an undo action. However, the only answers I found gave suggestions to use a Command or Memento pattern. I know this is most probably the way to go. What I'm asking for is how to integrate this as cleanly & extendable as possible in an MVC design.
[Edit] What I don't like about the Memento pattern is that it forces me to store a complete state. Let's say my model is a 1000x1000 matrix and my Command is ChangeOneValueAtLocation. To be able to undo its changes, the ChangeOneValueAtLocation object only needs to store the previous value of the location it's changing, but that doesn't seem possible with Memento. The larger my model, the biggest this problem becomes.
[Edit 2] Another problem I have with Memento in the specific case of this application: for every method a Command object can execute on the Model, there's a method that does exact opposite (or can easily be coaxed to do so). This is why I would find it a waste to have to store the whole state, there should be no need to, reverting a single Command is very straightforward, the only problem is getting the data to be able to do it.
Also, I don't need to be able to undo a specific Command, only the topmost one on my history stack.
I also support the model layer containing undo support. There are quite a few ways to handle this in the model side. The first and most obvious is the models themselves remembering the history of the changes with "labels", but this is probably going to be difficult to synchronize for all your model classes.
One other option is to create a history manager that has a concept of a "transaction", which causes it to generate an undo point, and take a snapshot of your models, or start recording changes (for reduced memory usage), or record commands that cause model changes, etc.The models notify the manager on change, and finally you complete the transaction (or not, because the next start of transaction can be the end of the previous one). Once you add in the ability to rollback to a certain point, the work will be done. By making things slightly more complicated in this manager class, you can create an undo tree (like the one in emacs), so it is also quite a flexible way to approach it.
The above solution is not quite in the model layer, though. It is a support class that is driven by both the model and the controller. If you remove the transaction concept, then it is completely model-driven, but implementing the concept of an undo operation might be somewhat tricky. If you change it to act as a command proxy, it is the only entity used by your controllers, and is clearly a model. It is too rough a design at this point to choose one approach over another, but I am leaning towards the "transaction" model. It feels easy enough to implement.
I'd really recommend building the undo tree into your Controller
Building it into the model could run you into trouble:
the 'model' is usually fragmented per view (each view has it's own partial model)
this will lead to non-atomic undo (undoing part of an operation due to the view not knowing what other things (models) would have to be undone etc)
The controller is the 'action dispatcher', so it'd have to say
clone state (all models) snapshot
add action to history with reference to snapshot
run action
then undo would be
pop action off history stack (optionally push to 'future' stack)
restore snapshot
display view
Also, make undo work with highlevel actions (see Composite Pattern or Command Pattern)
Build the undo functionality in your model itself. Let you model keep a list of commands. Run the commands in the reverse order when your view passes an undo signal to the model.