I am writing a Django app, and I would like an account to be created on our Google Apps hosted email using the Provisioning API whenever an account is created locally.
I would solely use signals, but since I would like the passwords to be synchronized across sites, I have monkeypatched User.objects.create_user and User.set_password using wrappers to create Google accounts and update passwords respectively.
Monkeypatching seems to be frowned upon, so I would to know, is there a better way to accomplish this?
Have you considered subclassing the User model? This may create a different set of problems, and is only available with newer releases (not sure when the change went in, I'm on trunk).
Subclassing seems the best route, as long as you can change all of your code to use the new class. I think that's supported in the latest release of Django.
Monkeypatching is definitely bad. Hard to say anything since you've given so little code/information. But I assume you have the password in cleartext at some point (in a view, in a form) so why not sync manually then?
I subclass User with Django 1.0.2. You basically makes another table that links to the user_id.
class User(MyBaseModel):
user = models.OneToOneField(User, help_text="The django created User object")
and then at runtime
#login_required
def add(request) :
u = request.user.get_profile()
You can then easily overwrite the needed methods.
And for those that hadn't heard of monkeypatching : http://en.wikipedia.org/wiki/Monkey_patch. It is a derivation from guerrilla patch.
Related
I'm creating a Django website that supports both local login backend and LDAP login (through django-auth-ldap), and maybe more in the future.
I'm getting into Django login and backends sutff and have a couple of questions - mainly is there any reason Django doesn't keep user creation backend in the database? Shouldn't user A be linked (and by linked I mean a field on User model) with the backend django.contrib.auth.backends.ModelBackend for safety/convince reason?
I'm getting around to creating a custom user model, and was thinking about adding such field. The ability to unambiguously know which backend was/is used to create/login the user sounds logically for me, but the fact that Django doesn't have that by default, and that I can't find anything similar on the Internet has me worried that I didn't think of a really good reason for why it's done the way it is.
Thanks in advance,
Paweł
Django doesn't need that info. Once the user is authenticated, and django has a User model, it doesn't care what backend authenticated it. The User model data is stored in one source. The User model (whether the default or custom) is consistent and has the same attributes, functionality and behaviour across the entire django project and schema. Nothing in the out-of-the-box django deals with different user models.
You may extend this with AbstractBaseUser, but managing really different users across the same project, especially with the core django modules, is a strech.
Django uses the User model a lot, and you will have to manually locate each place it does, and provide your own router to the correct backend. There is no API for this (like, say, db routers), it's going to be a mess of hacks that will probably even messier with each upgrade.
Django does support, in addition to the custom user model, "authentication backends". Some of the functionality your are looking for is available and exposed with this option, in a formal API. So you probably want to stick with that.
see:https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#authentication-backends
I am using Flask-Security to build a web app that has a public REST API. I am trying to figure out how to add user registration and login using REST calls only.
It is fairly easy to create a user using user_datastore.create_user. But how can I then login the user, using a REST call?
If flask_security.utils.login_user took username+password or a token as an argument, it would be easy, but it takes a user object instead?
The documentation shows how to register and login using forms and views, but I need to be able to register and login from an IOS device (using RESTkit).
You will either want to use flask_security.decorators.auth_token_required along with SECURITY_TOKEN_AUTHENTICATION_KEY or SECURITY_TOKEN_AUTHENTICATION_HEADER (depending on whether you want to pass the token in the URL or in a header) or you can override flask_security.core.UserMixin.get_auth_token for your User class and Flask-Security will do the right thing.
[Writing an answer since I do not have enough credentials to comment on answer provided by Sean Vieira]
I looked a bit of Flask-Security code - it uses Flask-Login's LoginManager for this.
Flask-Login in turn expects the user to define token_loader (as well as implement get_auth_token in User class)
Does Flask-Security provide "default" token_loader functionality ? Otherwise - it is same as Flask-Login
Edit:
It turns out Flask-Security works just fine. I do not need to write my own token_loader.
I had security code in a separate file, and that is how "magic" broke.
I brought back the security code into myapp/init.py - and documented code "works"
Edit 2:
Refering to answer provided by Sean above. I don't think it is one or the other. One must use auth_token_required decorator.
Overriding get_auth_token in User class is optional, in case you want different implementation for token generation (I think)
Overriding get_auth_token in User class is not sufficient.
I am starting web project that should be very flexible and modular and definitely will grow much in the future. As we plan to provide an api to other developers I started thinking that maybe it is a good idea to implement all the methods as api and provide functionality to use them remotely and internally.
For instance, say we want to extract all registered Users. So we design method in api, like get_all_users,which maybe available via REST or internal invocation. The problem is I cannot figure out how to distinguish access from internal usage and remote usage, as I should take into consideration also speed of internal invocation,code reusage and checking of user permissions(secret keys for api access, etc). What are the best practices? How to organize such API?
So to build the API, Tastypie or Piston. These let you write 'resources' (which are basically API versions of the views) - instead of returning httpresponses you just return objects which piston/tastypie convert into json or xml or yaml or whatever your favorite data-language is.
Securing the access: Consider decorating any resources which contain confidential information with the #login_required or #staff_member_required decorator as appropriate.
You might even want to go a step further and write a decorator to check that the staff user is using https (whereas you might allow a normal user to use any connection type).
If you have not considered it yet I recommend to use Tastypie to set up an API with django.
In order to distinguish between your internal and remote usage maybe you can simply design a different URL scheme.
I am a seasoned .Net developer who's trying to write some Python code. On one of the projects I am contributing to, we have a services layer which is a set of classes which abstract away functionality and a django web app which consumes these in process services (which are just classes).
I had created a repository layer and ensured that all interaction with the database happens through the services layer through this repository. We have a document oriented database and thus we do not have the usual object-relational muck.
During a recent code review, one developer who is supposedly seasoned with python shunned at this and commented that this was not the python way of doing things. He remarked that python developers are used to having a save and delete method on the object instance itself (and do not use the repository pattern as much) and this would confuse python devs looking to contribute to our OSS project. Python devs, your views? Would you be confused?
Edit: This is not django code, but will be code called by the django app (It an in process service layer)
Maybe that is a Django pattern, but not a Python one by all means.
That said, if the target audience of your module are Django developers, I would advise you to follow as much as possible the Django philosophy and its associated patterns.
Django's ORM provides save() and delete() methods on the object. SQLAlchemy on the other hand has a so called session to which you add or delete objects.
Both are very popular so I'd say that both methods are about equal in terms of popularity. However in the context of a Django application going with the Django convention is probably preferable unless you have a good reason not to.
Best of my recollection Django's models include save() and delete() methods so you can deal exclusively with objects, rather than interacting with a database connection object. I don't know that it's instantly a Python way of doing things, but I'm pretty sure it's a pervasive Django pattern.
If I was told "this is Django code" but the code diverged from how Django does things, that might be confusing.
Don't Repeat Yourself. If all the data stored in the database is meant to be accessible through django (e.g., they are defined in the django models.py); there's a django-ORM that is already designed to safely (no SQL injection) and easily access the database for you via save() and delete(). There's also helpful wrapper functions to create transactions (e.g., #transaction.commit_on_success to group together actions. You can use the ORM in python scripts outside of the running django web-app. E.g., create a django management command or run a script from the django shell (./manage shell)
I definitely agree having another repository layer creates confusion and potentially leads to major issues for people using your . E.g., sometimes you have model validation that goes beyond the database validation and if you save it outside of django that validation never runs. Or maybe every time a specific model is saved, extra behavior should occur (like creating a complimentary object; or generate a task) that would be skipped if save() is not called so the pre_save post_save signals are never generated.
Granted you said this is a document-oriented-database (e.g., mongdb/couchdb), and AFAIK django does not support these sorts of NoSQL dbs, so then ignore what I said.
What are the pros and cons of using open id vs auth? Shoud I do both?
That depends whether you want to support Open ID. As to the reasons behind Open ID, in my view the most compelling one is that it avoids requiring your users to have an account just for your site, with all the hassle that involves (yet another username and password to remember).
If you decide you want to use Open ID, there's not need to choose between that and auth - use django-openid-auth, which adds Open ID support to the auth framework.
Definitely try and avoid using an Open ID implementation that doesn't plug into Django's auth framework - you'll lose a lot of the baked-in goodness of Django (model-level permissions etc).
OpenID and OAuth do different things. OpenID lets users log into your site. OAuth lets people give your site access to their data elsewhere. On the other side of the coin, OAuth gives you a secure way to let users access their data in your service from elsewhere.
If you implement OpenID, don't implement an OpenID producer. Everyone's already got an OpenID, whether they know it or not. Just consume openids from elsewhere. Migrating OpenIDs shouldn't be hard. Just make sure that a user account can connect via multiple OIDs, then they can add new ones as needed, and remove when they're done with them.
Edit: Just saw that you were talking about django auth, not oauth. Oops. The second paragraph still stands.