What I need to know is the following:
1. how do I write my own login controller that will explicitly set the
identity for any future requests.
2. how do I logout.
So far, I'm able to add users to DB, no problem. But looking at the
identity code and the saprovider code, I am getting lost (I'm somewhat
of a Python newbie, ex-Java). In Java, you usually have pretty
explicit static typing to use when analysing other folks code. I find
that in Python, this is not possible, thus you really have to dig
quite deep to figure out where things are coming from. I'm not making
much headway there.
Any help will be very much appreciated.
Thanks,
Jesse James
In general terms, what identity is doing is associating a 'visit'
session (everyone visiting the site gets a unique visit key) with a
user. This starts out in the visit module (http://tinyurl.com/
376wae). Roughly, this works like:
- Identity receives a new request, and eventually routes it to
identity_from_request
- identity_from_request tries to authenticate via the methods you
specified in the config (default to form,http_auth,visit). form and
http_auth basically check for credentials in the request, and the
visit check (via identity_from_visit) asks the identity provider to
return a user
- if all the authentication methods fail, the identity is set to
anonymous
Ok, that's the authentication path. Now, when a user doesn't have
appropriate permissions, (i.e. the identity.require check fails), an
IdentityFailure exception is raised, which brings up the login form
(http://tinyurl.com/2j3ecm).
Logging out is done by removing the association between the user and
the visit key. This happens in SqlObjectIdentity or SqlAlchemyIdentity
via the logout() method. Or, in a controller, by calling
identity.current.logout()
Ok, so, where does that leave you. I'm not sure, so you may want to
ask more questions. Some things to think about.
If you set identity config options like:
identity.failure_url="/my_failure_url"
identity.source="visit"
You would get rid of the redirect to the login form. my_failure_url
could be a controller that raises an Unauthorized exception, or
perhaps shows an error page. You could then setup your own login form
and controller that explicitly associated the user with the visit key,
using identity.current_provider.validate_identity, and bypass
identity's default form login altogether. The caveat is that the only
way to authenticate will be through your new login form, but it sounds
like that is what you want anyways.
@tg.expose()
def login(self, username, password):
result = 'ok'
user=User.get_by(user_name=username)
if(user):
if(user.password == password):
identity.set_current_identity(user)
else:
result = 'invalid login'
else:
result = "invalid login"
return result
On Feb 22, 5:57 am, "Patrick Lewis" <patrickhle...@gmail.com> wrote:
> On Feb 21, 7:25 pm, "Jesse James" <joel.re...@gmail.com> wrote:
>
>
>
> > Howdy,
> > I am using SqlAlchemy under TG and Flash (with FlexBuilder 2) for the
> > UI.
> > I'm trying to figure out how to get login/logout and @require
> > decorator to work for me.
> > I am not walking down the garden path of using Kid and SqlObject so it
> > is not really set up right out of the box. Rather I am attempting to
> > leverage the auth framework in TG but with different needs from the
> > standard template-based app - I need much more explicit rejection of
> > unauthorized access attempts (not redirects to a login screen). Upon
> > login, however, it seems that it should be quite straightforward to
> > setup theidentity, yes?
>
> > What I need to know is the following:
>
> > 1. how do I write my own login controller that will explicitly set the
> >identityfor any future requests.
> > 2. how do I logout.
>
> In general terms, whatidentityis doing is associating a 'visit'
> session (everyone visiting the site gets a unique visit key) with a
> user. This starts out in the visit module (http://tinyurl.com/
> 376wae). Roughly, this works like:
>
> -Identityreceives a new request, and eventually routes it to
> identity_from_request
> - identity_from_request tries to authenticate via the methods you
> specified in the config (default to form,http_auth,visit). form and
> http_auth basically check for credentials in the request, and the
> visit check (via identity_from_visit) asks theidentityprovider to
> return a user
> - if all the authentication methods fail, theidentityis set to
> anonymous
>
> Ok, that's the authentication path. Now, when a user doesn't have
> appropriate permissions, (i.e. theidentity.require check fails), an
> IdentityFailure exception is raised, which brings up the login form
> (http://tinyurl.com/2j3ecm).
>
> Logging out is done by removing the association between the user and
> the visit key. This happens in SqlObjectIdentity or SqlAlchemyIdentity
> via the logout() method. Or, in a controller, by callingidentity.current.logout()
>
> Ok, so, where does that leave you. I'm not sure, so you may want to
> ask more questions. Some things to think about.
>
> If you setidentityconfig options like:
>
> identity.failure_url="/my_failure_url"identity.source="visit"
>
> You would get rid of the redirect to the login form. my_failure_url
> could be a controller that raises an Unauthorized exception, or
> perhaps shows an error page. You could then setup your own login form
> and controller that explicitly associated the user with the visit key,
> usingidentity.current_provider.validate_identity, and bypassidentity'sdefault form login altogether. The caveat is that the only
http://paste.turbogears.org/paste/1067
class User(object):
# ... quickstart boilerplate skipped....
def identity_login(self):
ident = identity.current_provider.authenticated_identity(self)
key = visit.current().key
ident.visit_key = key
identity.set_current_identity(ident)
vi = session.query(VisitIdentity).selectfirst(
VisitIdentity.c.visit_key==key)
if vi is None:
vi = VisitIdentity(visit_key=key, user_id=self.user_id)
session.save(vi)
else:
vi.user_id = self.user_id
On Feb 25, 12:54 pm, "Jorge Vargas" <jorge.var...@gmail.com> wrote:
> both of you could improve your code with this function.http://trac.turbogears.org/browser/tags/1.0.1/turbogears/identity/__i...
On Feb 25, 12:54 pm, "Jorge Vargas" <jorge.var...@gmail.com> wrote:
> both of you could improve your code with this function.http://trac.turbogears.org/browser/tags/1.0.1/turbogears/identity/__i...
>
I believe everyone in this thread is already using
set_current_identity. In what way are you suggesting this could be
improved?
So, we have established that Rick could not seem to get the identity
assignment to 'stick' without the code he presented.
Is that the general consensus ???
my original question remains:
How should I properly log in a user without the boiler plate login
template?
I don't know if it's the best way, but one way is:
identity.current_provider.validate_identity(u.user_name, u.password,
identity.current.visit_key)
Regards -- Andy
Surely there must be a way to log in a user without having to provide
a password. Otherwise this is a restriction on many other types of
authentication.
--
Ben Sizer
I think my PasteBin code (in this thread) should work, as well as
Rick's code (if you can get a User object).
Have you tried either of these and had problems?
What types of authentication are there that don't require a password
or secret of some type? It's an honest question; I'm not familiar with
any.
Well for starters, there might actually be a password, but it's
handled remotely. eg. You may submit the username and password to some
sort of trusted service on the local network, which can then grant or
deny access. You may have existing code for doing this, and won't want
to hack the identity provider or whatever it is to have to relay that
password on (which I assume is possible, though I haven't checked).
Or you might just grant access based on IP address, such as admin
rights automatically granted to localhost. Or it could just be a low-
security shared system, eg. an intranet wiki, where you just go by
username and don't want to burden people with passwords.
Maybe you don't store any important data that persists across visits,
and instead just want to equate one 'user' with one extended visit to
the site, but find it convenient to use identity to tie the data
together across multiple HTTP requests, after an implicit login.
Perhaps you're sharing a domain with a legacy PHP site, and while
slowly migrating over to Turbogears, you want the cookie that your PHP
login script sets to allow you to access restricted parts of your TG
app.
Or you might desire some sort of 'su' functionality where someone
logged in as an administrator can log in as someone else instantly -
for this you'd want to be able to just reassign the identity
accordingly.
Sure, many of these are somewhat uncommon, and I expect many or most
can be hacked around with new identity providers, but I don't know how
easily more than one such provider might co-exist within one app for
example. I think it would be beneficial to expose a function that
allows people with advanced authentication purposes to simply reassign
the current user.
--
Ben Sizer
On Feb 28, 5:14 am, "Ben Sizer" <kylo...@gmail.com> wrote:
def login(self,username,password):
ident = tg.identity.current_provider.validate_identity(
username, password, cherrypy.request.tg_visit.key)
if ident:
result = 'ok'
else:
# credentials weren't valid, so user is anonymous
ident = tg.identity.current_provider.anonymous_identity()
result = 'invalid login'
# manually set identity in case we
# want to use it elsewhere in this request
tg.identity.set_current_identity(ident)
return result
then, no, I haven't tried it yet, but I now have this high on my todo
list.
Thanks, I'll let you know ASAP.
Jesse
Unless someone has a good way of delegating identity authentication to
outside sources that handles that at a higher level, yes.
If identity could easily accommodate multiple providers, and could log
in a given user via an appropriate function without having to supply
any sort of password, then you wouldn't need to assign anything
directly. I'd prefer the framework to evolve to better handle those
situations.
--
Ben Sizer