@login_required, headers, session/cookie

325 views
Skip to first unread message

Sylvain

unread,
May 24, 2011, 9:55:23 AM5/24/11
to ProtoRPC Discuss
Hi,

I'm developping a new project with ProtoRPC.
ProtoRPC seems really nice, fast, easy... thank you !

I've 2 questions about it :

1) What is the best solution to limit some services (remote.method) to
an appengine administrator ?
Are there something like these "decorators" @login_required, login:
admin

http://code.google.com/intl/fr/appengine/docs/python/tools/webapp/utilmodule.html
http://code.google.com/intl/fr/appengine/docs/python/config/appconfig.html#Requiring_Login_or_Administrator_Status

2) How to read/write http request/response headers ?
Currently it seems not possible ?
And so, is there a solution to use session/cookie management ?

Regards

Sylvain

Rafe Kaplan

unread,
May 24, 2011, 3:24:57 PM5/24/11
to google-prot...@googlegroups.com
>
> I'm developping a new project with ProtoRPC.
> ProtoRPC seems really nice, fast, easy... thank you !
>
> I've 2 questions about it :
>
> 1) What is the best solution to limit some services (remote.method) to
> an appengine administrator ?
> Are there something like these "decorators" @login_required, login:
> admin
>
> http://code.google.com/intl/fr/appengine/docs/python/tools/webapp/utilmodule.html
> http://code.google.com/intl/fr/appengine/docs/python/config/appconfig.html#Requiring_Login_or_Administrator_Status


If you are ok with decorating the entire service, I would recommend
covering it by another WSGI middleware application. A middleware
application is a WSGI application that wraps another WSGI application.
webapp is a type of WSGI application and can be wrapped as normal.

Here is an example WSGI middleware filter you might implement:

def require_login(app, admin_only=False):
# This is the function that will wrap your webapp application.
def require_login_app(environ, start_response):
user = users.get_current_user()
if not user or (admin_only and not users.is_current_user_admin()):
# Sends HTTP error response without ever calling webapp.
start_response('401 Unauthorized', [])
return ['You can put error text here']
else:
# This will call webapp
return app(environ, start_response)

Then you can do:

service_mappings = service_handlers.service_mapping(
[('/hello', HelloService),
])

application = webapp.WSGIApplication(service_mappings)
application = require_login(application)

def main():
util.run_wsgi_app(application)


This version, since it is an RPC interface, does not attempt to send
back any redirections.

If you need to block individual methods, for now you might choose to
provide require_login with a list of methods that require auth.

There will be more complete solutions built in to ProtoRPC in the future.


>
> 2) How to read/write http request/response headers ?
> Currently it seems not possible ?
> And so, is there a solution to use session/cookie management ?
>

In the future, I'm hoping to make it easy to do HTTP header handling
outside of the service. Typically services should not rely on HTTP
headers since they are meant to be independent of the underlying
protocol.

However, since we live in the real world, you can use
remote.Service.request_state :) request_state is an instance of
remote.HttpRequestState, which includes a wsgiref.headers.Headers
instance.

Maxim Lacrima

unread,
May 25, 2011, 6:15:13 AM5/25/11
to google-prot...@googlegroups.com
Hi Rafe!


On 24 May 2011 22:24, Rafe Kaplan <ra...@google.com> wrote:
>
> 2) How to read/write http request/response headers ?
> Currently it seems not possible ?
> And so, is there a solution to use session/cookie management ?
>

 In the future, I'm hoping to make it easy to do HTTP header handling
outside of the service.  Typically services should not rely on HTTP
headers since they are meant to be independent of the underlying
protocol.

 However, since we live in the real world, you can use
remote.Service.request_state :)  request_state is an instance of
remote.HttpRequestState, which includes a wsgiref.headers.Headers
instance.

Does it mean that I can set headers in the service method like this: self.request_state.headers.add_header('header', 'value')
I tried this, but it doesn't seem to work.

Also what is the purpose of initialize_request_state() method? Is it intended to be used for preprocessing incoming request state (e.g. request headers) for more convenient reuse by service methods?


--
with regards,
Maxim

Rafe Kaplan

unread,
May 25, 2011, 1:16:00 PM5/25/11
to google-prot...@googlegroups.com
>
> Does it mean that I can set headers in the service method like this:
> self.request_state.headers.add_header('header', 'value')
> I tried this, but it doesn't seem to work.
>

That's true, the service can receive incoming headers but cannot set
outgoing headers. May I ask what kinds of headers you are looking to
set? I'm going to suggest using WSGI middleware to manage headers to
the client, but I'd like to see what your use case is to see if there
is a better way or a need to change the implementation.

> Also what is the purpose of initialize_request_state() method? Is it
> intended to be used for preprocessing incoming request state (e.g. request
> headers) for more convenient reuse by service methods?
>

That is it's purpose. I think most header processing should happen
in a WSGI middleware layer but right now there is not a lot of
knowledge about how to do that, and for many developers, that kind of
solution might complicate their code too much.

Sylvain

unread,
May 25, 2011, 5:26:17 PM5/25/11
to ProtoRPC Discuss
Hi Rafe,

Thank you for this idea, the WSGI middleware.
But I don't think it's very easy to use.

I'd prefer something like this :
* a new parameter inside the @method decorator
* or a new decorator

---------------
class PostService(remote.Service):

@remote.method(Note, message_types.VoidMessage, admin_only=True)
def post_note(self, request):
---------------

---------------
class PostService(remote.Service):

@admin_only
@remote.method(Note, message_types.VoidMessage)
def post_note(self, request):
---------------

Currently, I think I will create an adminservices.py and add
"login:admin" to this handler it in the app.yaml

- url: /adminservices.*
script: adminservices.py
login: admin

Same thing for the protorpc form :

- url: /protorpc.*
script: services.py
login:admin

These services must be only use by an admin.
It should work.

Regards

Sylvain



On May 24, 9:24 pm, Rafe Kaplan <ra...@google.com> wrote:
> > I'm developping a new project with ProtoRPC.
> > ProtoRPC seems really nice, fast, easy... thank you !
>
> > I've 2 questions about it :
>
> > 1) What is the best solution to limit some services (remote.method) to
> > an appengine administrator ?
> > Are there something like these "decorators" @login_required, login:
> > admin
>
> >http://code.google.com/intl/fr/appengine/docs/python/tools/webapp/uti...
> >http://code.google.com/intl/fr/appengine/docs/python/config/appconfig...

Rafe Kaplan

unread,
May 25, 2011, 5:43:26 PM5/25/11
to google-prot...@googlegroups.com
Ah, that's probably the best way. I was assuming you didn't want to
use the app.yaml for access control.

Maxim Lacrima

unread,
May 26, 2011, 9:42:44 AM5/26/11
to google-prot...@googlegroups.com
Hi Rafe!

Thanks for your help!
Basically I want to implement custom authentication middleware. For this I need to check/set cookies on every request from the client. How would you recommend to implement this?

Below is an example how we can define middleware in tipfy. Probably in future this could be solution for protorpc too, but I am nor sure.
class SomeMiddleware(object):
    def after_dispatch(self, response):
        """Called before service method was executed"""
        pass
    def after_dispatch(self, response):
        """Called after service method was executed"""
        pass

  class SomeService(remote.Service):
     middleware = [SomeMiddleware()]

     @remote.method(MyMessage1, MyMessage2)
     def do_something(self, request):
         pass
--
with regards,
Maxim

Sylvain

unread,
May 28, 2011, 12:59:46 PM5/28/11
to ProtoRPC Discuss
Yes, I'd like to set/get cookie on every request too.

Rafe Kaplan

unread,
May 31, 2011, 9:06:29 PM5/31/11
to google-prot...@googlegroups.com
I recommend implementing middleware separate from ProtoRPC that
deals with the cookies. If you are using the cookie to retrieve
session information from the request and share it with the services,
unfortunately there are only two ways to get access to that
information. Either use a global variable, the same way
users.get_current_user() on App Engine does, or put information in to
a custom HTTP header. Probably the easiest thing to do:

def manage_session(app):
def session_app(headers, start_response):
global session
session = parse_cookie_to_session(headers.get_all('cookie'))

def session_start_response(status, response_headers):
response_headers.append(('set-cookie', session.to_cookie()))
return start_response(status, response_headers)

return app(headers, session_start_response)
return session_app

Currently this is a little bit convoluted, however, there will be
better support for this sort of thing in the future.

Rafe Kaplan

unread,
May 31, 2011, 9:09:55 PM5/31/11
to google-prot...@googlegroups.com
I should have also pointed out how to use the example WSGI
middleware with webapp. The way that middleware is typically used is
that it wraps another WSGI application. In this case, the other WSGI
application is the webapp application.


application = webapp.WSGIApplication(
service_handlers.service_mapping(...))

application = manage_session(application)

Sylvain

unread,
Jun 4, 2011, 12:55:47 PM6/4/11
to ProtoRPC Discuss
Hi,

The request_state.headers is a list.
Maybe a dict would be easier to read ?
Why did you change the original self.request.headers to a list ?

Regards

Sylvain

Rafe Kaplan

unread,
Jun 7, 2011, 3:55:59 PM6/7/11
to google-prot...@googlegroups.com
request_state.headers is an instance of wsgi_headers.Headers:

http://docs.python.org/library/wsgiref.html#module-wsgiref.headers

It's actually intended for WSGI responses, an the request headers is
meant to be request headers. It needs to be a list instead of a
dictionary because dictionaries do not support multiple values. It's
possible for an HTTP request to have multiple values for the same
header name.

It might make sense to change it to something else, but I'm afraid
using a dictionary may not be adequate.

Rodrigo Moraes

unread,
Jun 22, 2011, 8:08:18 PM6/22/11
to ProtoRPC Discuss
On May 25, 2:16 pm, Rafe Kaplan wrote:
>   That's true, the service can receive incoming headers but cannot set
> outgoing headers.  May I ask what kinds of headers you are looking to
> set?

Am I right that we can't easily set the response status code using a
remote.Service alone?

-- rodrigo

Joe Tyson

unread,
Jun 22, 2011, 8:30:33 PM6/22/11
to google-prot...@googlegroups.com
Well, you can raise different exceptions which will have some effect
on status code. There's no direct access to the response from the
service, though. I'm not sure having direct access to the status code
is safe, either... I think any http based transport implementation
will want to agree that any successful request responds with status
code xxx, and any error response is yyy or yyx.

Is there a specific status code or problem you're shooting for?

Rodrigo Moraes

unread,
Jun 23, 2011, 4:10:52 AM6/23/11
to ProtoRPC Discuss
On Jun 22, 9:30 pm, Joe Tyson wrote:
> Is there a specific status code or problem you're shooting for?

The ones mentioned in this thread. 401 or 403, for example. Or others
for when things go wrong. 400 and 500 are easier to achieve with
exceptions, but what is the correct way to return a response with a
short reason message? I'd like to do this in the remote.Service level.
For now I'm returning a 200 with a status "False" and a reason string
in a response message. It feels a little weird.

-- rodrigo

Joe Tyson

unread,
Jun 23, 2011, 11:32:22 AM6/23/11
to google-prot...@googlegroups.com
Agreed, that does feel a little weird.

You can raise remote.ApplicationError and pass in a special error
message and error name:

class MyService(remote.Service):
@remote.method
def raise_application_error(self, request):
raise remote.ApplicationError('Some Error Message!', 'ERROR_NAME')

This will set the status to 400, and return an RpcStatus message,
which will contain our error message and error name passed in above:

{
"state": "APPLICATION_ERROR",
"error_message": "Some Error Message!",
"error_name": "ERROR_NAME"

Murph

unread,
Jul 5, 2011, 2:11:48 AM7/5/11
to ProtoRPC Discuss
I have to agree. I'm just getting started with ProtoRPC, and it does
seem an odd limitation to be limited to only 200, 400, and 500
responses with HTTP transport. It would be lovely to be able to
respond with at least 401, 403 and 404, but it should possibly be
expanded to just allow for any 4xx or 5xx code.

On Jun 23, 4:32 pm, Joe Tyson <joety...@gmail.com> wrote:
> Agreed, that does feel a little weird.
>
> You can raise remote.ApplicationError and pass in a special error
> message and error name:
>
>   class MyService(remote.Service):
>     @remote.method
>     def raise_application_error(self, request):
>       raise remote.ApplicationError('Some Error Message!', 'ERROR_NAME')
>
> This will set the status to 400, and return an RpcStatus message,
> which will contain our error message and error name passed in above:
>
>   {
>     "state": "APPLICATION_ERROR",
>     "error_message": "Some Error Message!",
>     "error_name": "ERROR_NAME"
>   }
>
> On Thu, Jun 23, 2011 at 1:10 AM, Rodrigo Moraes
>
>
>
>
>
>
>
> <rodrigo.mor...@gmail.com> wrote:
> > On Jun 22, 9:30 pm, Joe Tyson wrote:
> >> Is there a specific status code or problem you're shooting for?
>
> > The ones mentioned in this thread. 401 or403, for example. Or others

Joe Tyson

unread,
Jul 5, 2011, 4:12:30 AM7/5/11
to google-prot...@googlegroups.com
I think it's important not to become too dependent on http status
codes. In our case, ProtoRpc has an "RpcStatus" which is responsible
for representing the success or error states of a method call. While
this may seem redundant given that Http also implements a state
mechanism for error/success, protorpc doesn't know if a service is
always used over Http.

Think of http more as a dumb channel. As a client, the http channel
needs to be able to tell me if the server encountered an error or not.
The only errors the channel should be concerned with are errors where
the server couldn't be reached (network error), where the server
replied unexpectedly (server error), or where the server returned
*some* application specific error (application error). If we build
services to depend more on ApplicationErrors, we shouldn't need to
worry about status codes. Authorization problem? Application error.
User not found? ApplicationError. If we do this, we can implement our
Rpc over any number of transports given that they can transmit an
error state.

I think error raising could use some improvement (and documentation).

Murph

unread,
Jul 15, 2011, 4:14:03 AM7/15/11
to ProtoRPC Discuss
You're absolutely right that error raising does need some
documentation and improvement.

I've thought about this for a few days now, and I can't agree that 400
is sufficient or even appropriate for application errors. For some
developers, other transport protocols are irrelevant, we are only
developing for an HTTP service environment — that is simply a design
decision for some applications (one which they may or may not come to
regret in the future). Not being able to support a reasonably full
set of HTTP status codes makes this library a less attractive choice
as-is (remember, the far end might not have any possibility of having
a formal ProtoRPC implementation, without significant development by
the service provider, e.g. Second Life's LSL).

In the case of ApplicationError being the only option that allows us
to return our own message easily, it actually means we are forced to
be non-compliant with RFC2616 §10, in some cases. At present, we are
only able to return a 400 status code, if we want to signal an error,
and use the RpcStatus message to supply details on the specific issue
to the client, leading to 2 problems as far as standards compliance
with HTTP/1.1 goes:

1) RFC2616 §10.4, "Client Error 4xx", specifies "The 4xx class of
status code is intended for cases in which the client seems to have
erred." That makes any 4xx code generally inappropriate for where we
are trying to communicate an error in the application or server
itself, rather than with the data supplied by the client (e.g.
datastore unavailable or read only), or some characteristic specific
to the client.

2) RFC2616 §10.4.1, "400 Bad Request", specifies "The request could
not be understood by the server due to malformed syntax." That makes
the 400 code quite inappropriate for many of the cases which we
actually want to communicate back to the client. In fact, it may make
it entirely inappropriate for the ApplicationError case, as syntax
validation should be performed by the library. There may be other
cases, but it seems to me that we would only need to raise a 400 in
terms of its formal definition is where we are doing something like
using a string field to hold a more complex piece of data, and it has
failed validation at application level. In some cases, a §10.5.1,
"500 Internal Server Error" (The server encountered an unexpected
condition which prevented it from fulfilling the request.) would be
much more appropriate under the HTTP standard, but with a custom RPC
object in the body of the response, as with the current
ApplicationError. 403 would definitely be more appropriate for some
cases, than 400, such as being denied access based on source IP
address.

If it's really going to be a problem to support multiple codes, 500
may well be a better choice for a generic, catch-all error code, where
the body has to be inspected to determine the actual cause of failure,
at least in terms of the HTTP standard. RFC3205 (BCP56) supports this
viewpoint in §8, "Issues regarding use of HTTP status codes". The
usage of the at least some of various other HTTP status codes in
webapp/service_handlers.py is not an issue here under either RFC2616
or RFC3205, where they have actually been used for their purpose as
documented in the standard (e.g. missing content-type, bad HTTP
method).

Rafe Kaplan

unread,
Jul 15, 2011, 7:12:24 PM7/15/11
to google-prot...@googlegroups.com
Thank you for this post.  I think it's very helpful and informative.

I have to admit that it has not been easy trying to determine what is the right HTTP response to an application error condition.  There is a strong case that the HTTP layer has nothing to do with this so should always return 200 when a request succeeds, but given that part of the intent here is to use HTTP as a container, there actually is some interaction between the two strata.  For example, if you send a request in a format that the ProtoRPC request is not able to parse, it will respond with a 415 (in this case, no RpcStatus because it is does not speak the clients wire format).

Regarding RFC3205 8 I am most concerned about the point it makes about proxy mechanisms that modify error response codes.  That seems like the most likely place where ProtoRPC would run in to significant problems.  I feel like it's only a matter of time, for example, that my bloody internet provider starts trying to insert ads or something on every 500.  This is not a matter of adherence to specification but a matter of protocol operation.  A proxy that does this to a response could well turn a meaningful application exception in to an opaque ServerError.

I am less concerned about which specific HTTP error code is used for application errors, although ProtoRPC should define which it will be.  What is important is that there is a way to communicate to the client whether a message body is an RpcStatus or the method response-type.  I am looking for the best possible adherence to the HTTP spec, but can only do so where appropriate.

An alternative way to communicate application errors is to provide some other information in the response headers that the client must parse.  For example, an extension header:

  X-ProtoRPC-MessageType: protorpc.remote.RpcStatus

...or a parameter on content-type:

  Content-Type: application/json; charset=UTF-8, message-type=protorpc.remote.RpcStatus

I was hoping to avoid these types of approaches because they would complicate client implementation, particularly for people who want to write simple Javascript handlers without a client library, command-line tools, etc.  It also seems like just another way to bend the standard, which I admit to doing.

Unfortunately, HTTP is a standard that is about managing documents.  Even more unfortunately, it is the Universal Language of the Internet, and what we have available :)

Rafe Kaplan

unread,
Sep 12, 2011, 7:49:27 PM9/12/11
to Steven Bjorn Bonham, google-prot...@googlegroups.com
> Yes if you think this is a useful feel free to move it back to the group.
>

Thank you, it might help someone else in a similar situation.

> I am using the standard protobuf C++ libraries. I essentially created and
> compiled a .proto file that directly mirrors the protorpc messages that will
> be sent back and forth. All that communication is working and tested both
> requests and responses.
>
> As a note I am currently just using the Google App Engine sandbox on ubuntu
> and have not yet taken my app live.  What I meant by logged in: I used the
> simple Users API example to present the web browser (firefox) with a login,
> and then upon success, the user is redirected back to my sight. Being a
> newbie I just took it as magic that I could now open other web browsers and
> access my website and have it know that I was successfully logged in. I
> naively thought this would also apply to my QT application when sending its
> http requests with my protobuf payload because I successfully logged in on
> the web browser I hoped to now make it passed the authentication filter on
> the webserver. I was thinking I could just spawn a web browser from Qt,
> allow the client to login, and then all my Qt <-> webserver protorpc based
> messages would begin succeeding.
>

> After much poking around on the web and based on your reply I think I
> understand why the above does not work. So it sounds like going forward I
> have three options.
>
> 1. Allow the user to login via a webbrowser. This creates a cookie that
> grants access when included in http requests. Communicate this information
> to my Qt Client.
>      a. Since the cookie is stored locally on the disk I could go grab it
> and parse it from their?
>      b. I could present an interface to my webserver that allows the
> retrieval of cookies for a certain user, this doesn't seem to solve the
> problem though since anyone could then request that cookie for any user and
> then start making http requests on the users behalf.
>
> 2. App Engine client login. I assume this means Qt acts like a web browser
> and directly asks for the users credentials. Then it takes responsibility
> for authenticating the user and getting the cookie. I assume this is not
> recommended because my QT client now has direct access to the users username
> and password.
>

I feel like you almost have a good idea trying to spawn a browser,
but depending on how you are using that application it could well be
very brittle. But it may also be a security issue. Many users won't
hesitate to enter their user name and password but you are then adding
your application to the security chain between users and (often) their
gmail accounts. It could unknowingly by you be used as a vector for
hackers to access other peoples email. This is something a very much
do not recommend you do.

> 3. Oauth1. I have read a lot of articles about this and I think there is a
> library called kQOauth that supposedly does most of the dirty work for Qt.
> It seemed like the few threads I read indicated that folks were having
> trouble getting it to work with the google authentication system. Assuming I
> could get this to work I assume I would still present the user with a web
> browser and they would then grant me access on their behalf which would give
> me the cookie I need to make my protoRPC based html requests?
>

I do not know with certainty but I am worried that kQOauth will not
work with App Engines Oauth implementation because it is a somewhat
non-standard implementation. So it's not surprising people have had
problems with it, at least for the time being.

When you are using oauth you are not using any cookie based
authentication. You would need to either:

1) Always have users authenticate when they use your application
2) Implement storage for the applications authentication token so
that users do not need to authenticate every single time.

Unfortunately web standards are heavily evolved to favor the use of
browsers. So, adding this kind of support to a Qt based application
is definitely extra credit. It is my intent that ProtoRPC will
integrate better in the future with alternate authentication models,
but it's obviously a bit early on and we have not managed to sort out
all those issues yet. I therefore really appreciate the difficulty
you are having with this problem, it's not a trivial one. Poking
around on the internet, you will also find that everyone has trouble
with authentication.

>
> I really am trying not to over complicate things. I am up for any
> suggestions. In my basic use case the data being uploaded through protorpc
> is not really sensitive in itself and if it were intercepted it would not be
> the end of the world. However, only certain users that I have pre-approved
> (stored their email in the data store) will be allowed to ultimately upload.
> Lets say the payload was pictures, I wouldn't want some random user
> uploading inappropriate pictures on another users behalf.
>
> I am even up to do a more custom authentication system where I store user
> names and passwords that just work for my site. I would be willing to make
> the communication https so I could just send the user name and password with
> each protorpc communication. BTW does protoRPC work over https?

It should not have a problem working over https. You just need to
set those endpoints as being https and have your client support HTTPs,
which I'm certain Qt does.

Since it sounds like your software is in a relatively early phase of
development, I might recommend writing your own customized
authentication. Again, this authentication system should be
implemented at the WSGI middleware layer, and it can use dual
authentication (check to see if a user is logged in via app engine
authentication or the custom auth system). I have a feeling when you
get people working with your client it will become clearer what kinds
of additional support they will need. Later you can provide a better
authentication system.

>
> Sorry for the long email and I appreciate your response. I really like
> protoRPC and want to use it at all costs, but just need to get over this
> last hurdle somehow.
>

I really appreciate that you are interested in using ProtoRPC and I
am very interested in having developers use it. I do however,
sincerely hope that you do not do this at all costs :)

>
> Thanks in advance,
> Steve
>
>
> On Thu, Sep 8, 2011 at 3:14 PM, Rafe Kaplan <ra...@google.com> wrote:
>>
>>  First, may I move this back to the group?  It is likely to be useful
>> to others.
>>
>>  I like to hear that you are looking to use ProtoRPC with Qt.  Before
>> I go on, I'd like to ask, are you going to use the standard protobuf
>> library with it?  If it's helpful (and you are not going to have any
>> issue with the licensing) you might want to consider it.
>>
>>  If you want the Qt program to use the same session system as the
>> web-browser, you will need to implement cookies on that client.  That
>> means parsing and sending the appropriate cookie headers.
>>
>>  However, you mentioned something else, that your web browser is
>> logged in.  Do you mean that you are logged in via the standard App
>> Engine login mechanism?  If that's the case, there is substantially
>> more work that needs to be done in the Qt client.  It will either need
>> to do an App Engine "Client Login" (which is not a good idea) or you
>> need to change your application to use oauth.  What's worse, is that
>> right now only oauth1 is supported, and in a non-standard way (boo -
>> it will not be thus forever but it is now).
>>
>>  So, what parts am I understanding and what parts am I missing?
>>
>> On Wed, Sep 7, 2011 at 10:28 PM, sbonham <sbo...@gmail.com> wrote:
>> > Hello Rafe,
>> >
>> > I have tried implementing access control both using app.yaml as well
>> > as the middle wear example you suggested above. Both work great when
>> > my protorpc communication is initated from my browser using JSON.
>> > Without knowing all the details I assume a cookie/session/token or
>> > some combination is saved by the web browser so that any time I open a
>> > new browser the fact that I succesfully logged in is preserved and my
>> > protorpc communication succeeds. The problem is that I would like to
>> > invoke protorpc from a desktop application built with Qt. I have
>> > gotten all the communication to work with natively compiled C++
>> > protocol buffers. When I add the access control obviously the requests
>> > start failing. However, I obviously don't want just any old C++ app
>> > running to be able to post things to my eventual web server. What is
>> > the best way for my Qt based http request to succeed, i.e. to present
>> > a request to the web server that the user is succesfully
>> > authenticated. Is this even possible? Please let me know if my
>> > question is unclear.
>> >
>> > Thanks in advance,
>> > Steve


>> >
>> > On May 25, 2:43 pm, Rafe Kaplan <ra...@google.com> wrote:
>> >>   Ah, that's probably the best way.  I was assuming you didn't want to
>> >> use the app.yaml for access control.
>> >>
>> >>
>> >>

>> >> On Wed, May 25, 2011 at 2:26 PM, Sylvain <sylvain.viv...@gmail.com>

>> >> >> instance.- Hide quoted text -
>> >>
>> >> - Show quoted text -
>> >
>
>

sbonham

unread,
Sep 13, 2011, 11:46:57 AM9/13/11
to ProtoRPC Discuss
Thanks for all the suggestions and information. I might end up doing a
custom authorization but before I do I wanted to give google specific
OAuth a try. I read Oath 1.0 for installed applications which I think
applies to me. http://code.google.com/apis/accounts/docs/OAuthForInstalledApps.html.
So forgetting about KQOAuth lets assume I was able to navigate the
handshaking, ask the user for permission by spawning a web browser,
and then ultimately get an access token. This would be done through a
series of http and https requests from my QT application. Assuming I
have that token here are my questions with regards to protoRPC.

1. From Qt client application, if I sign each http post with my access
token will that get me through the basic users access control (either
set up by adding login: required to app.yaml or using middleware
access control suggested above)

2. Assuming this does work how do I access which "user" has just made
the protoRPC request from within my handler. i.e.
@remote.method(HelloRequest, HelloResponse)
def hello(self, request):
# How can I get the user? the obvious thing that comes to mind
is use:
# user = users.get_current_user()
# I suspect the above won't work since the user hasn't really
necesarily logged in, instead they have provided me with an access
token which
# I have signed and sent with this incoming request

3. "Determining the scope of the data your application will access"
This is mentioned in the OAuth link. What scope of data do I want
access to? I obviously don't need access to the users calendar or any
other google specific application besides my own Google App. What do I
specify for this level of access. It is this sentence that makes me
think I am thinking about OAuth in the wrong way.

4. Lastly since I am currently just using the GAE test sandbox, do you
have any suggestions for testing the above functionality before
actually trying to go live an get an actual access token using my own
google credentials. i.e. is there a way to get a bogus access token
for the "te...@google.com" user.

If I am completely off base here with OAuth please let me know and I
will attempy to use a custom authorization system as you suggested
above.

Thanks,
Steve
> ...
>
> read more »- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages