[google-appengine] How to download the source code of my app?

106 views
Skip to first unread message

ninety

unread,
May 10, 2010, 1:29:01 AM5/10/10
to Google App Engine
I'm a very beginner...
I lost the source codes of my app on my local PC but don't know if it
is possible to download it from the web..
Thanks a lot!

--
You received this message because you are subscribed to the Google Groups "Google App Engine" group.
To post to this group, send email to google-a...@googlegroups.com.
To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.

djidjadji

unread,
May 10, 2010, 7:45:58 PM5/10/10
to google-a...@googlegroups.com
Have you done a search on this list?
The result will be: that it can't and never will be.
Use source control and/or backup.

2010/5/10 ninety <lixinp...@gmail.com>:

Darien Caldwell

unread,
May 11, 2010, 11:24:17 AM5/11/10
to Google App Engine
Actually, you can, if you happen to have remote API enabled:

http://groups.google.com/group/google-appengine/browse_thread/thread/31025ae9b5332a2d/b81d150dcc39cf5c

In other instances, no.

djidjadji

unread,
May 11, 2010, 2:54:08 PM5/11/10
to google-a...@googlegroups.com
If it was possible to get the source code through remote_api or
appcfg.py-hacking it would be possible for the client who only has the
use right of the code to download it too. The client is administrator
of the app too.
This is not what a number of GAE developers would like to see possible.

2010/5/11 Darien Caldwell <darien....@gmail.com>:

Barry Hunter

unread,
May 11, 2010, 3:53:07 PM5/11/10
to google-a...@googlegroups.com
Well on the stackoverflow page linked from that thread, its written

"If your app was written in Python, and had both the remote_api and
deferred handlers defined, it's possible to recover your source code
through the interaction of these two APIs."

Written by Nick Johnson

Ikai L (Google)

unread,
May 12, 2010, 4:37:51 AM5/12/10
to google-a...@googlegroups.com
Oh, the grief caused by publishing this. Yes, there is a hack that currently allows you to retrieve source code, but we are greatly discouraging this. In fact, I am pretty sure the article says something to the tune of "before you do this, you should always, always, always back up your code and use source control!"
--
Ikai Lan 
Developer Relations, Google App Engine

----------------
Google App Engine links:
Blog: http://googleappengine.blogspot.com 

djidjadji

unread,
May 12, 2010, 4:40:47 AM5/12/10
to google-a...@googlegroups.com
If you want to prevent your client to download your code with the
method Nick describes just choose some random URLs for the remote_api
and the deferred handler

Your app.yaml part looks like

========================
- url: /vG68wMbHF0LFwYh
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin

- url: /KCtDS6p50mEetNE
script: $PYTHON_LIB/google/appengine/ext/deferred/handler.py
login: admin
========================

random URL generated with
-----------------
import string, random
chs = string.ascii_letters + string.digits
print ''.join( random.choice(chs) for i in xrange(15) )
-----------------

If you still want to download the source code with the method use the following

remote_api_shell.py your_app_id /vG68wMbHF0LFwYh

for the deferred call use

defer(eval, expr, _url='/KCtDS6p50mEetNE')


2010/5/11 Barry Hunter <barryb...@googlemail.com>:

djidjadji

unread,
May 12, 2010, 10:07:23 AM5/12/10
to google-a...@googlegroups.com
2010/5/12 djidjadji <djid...@gmail.com>:
> If you want to prevent your client to download your code with the
> method Nick describes just choose some random URLs for the remote_api
> and the deferred handler
>

The problem is that these random URLs are visible in the logs.

The only solution is to prevent the use of eval in deferred calls.
You must make your own deferred handler and filter out the use of eval.
app.yaml get setup like this

-----------------
- url: /_ah/queue/deferred
script: mydeferred_handler.py
login: admin
-----------------

mydeferred_handler.py is an adjustment of the default handler.py and
deferred.py parts for the execution of deferred tasks.

We also have to look for eval inside the run_from_datastore. And that
could be wrapped inside a run_from_datastore ....... Unpack the
request until we have an other function call.

In this deferred handler I have also disabled the INFO logging of
every deferred Task invocation.
This helps in browsing the log, no unneeded log entries.

And I use the logging.error to log the failure, this does not show a
stack trace.

Be sure to remove the CodeFile objects once you stored them locally.

------------------mydeferred_handler.py---------------------
# Alternative deferred handler to eliminate the execution of eval()

import logging
import os
import pickle

from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import deferred

def test_for_builtin_eval(func):
if func.__name__=='eval' and func.__module__=='__builtin__':
raise deferred.PermanentTaskFailure()

class _DeferredTaskEntity(db.Model):
data = db.BlobProperty(required=True)

def my_run_from_datastore(key):
entity = _DeferredTaskEntity.get(key)
if not entity:
raise deferred.PermanentTaskFailure()
try:
ret = my_run(entity.data) # prevent a run_from_datastore inside a
run_from_datastore
entity.delete()
except deferred.PermanentTaskFailure:
entity.delete()
raise

def my_run(data):
try:
func, args, kwds = pickle.loads(data)
except Exception, e:
raise deferred.PermanentTaskFailure(e)
else:
test_for_builtin_eval(func)
# test if we run from datastore
if func.__name__=='run_from_datastore' and \
func.__module__=='google.appengine.ext.deferred.deferred':
return my_run_from_datastore(*args,**kwds)
else:
return func(*args, **kwds)

class TaskHandler(webapp.RequestHandler):
def post(self):
#headers = ["%s:%s" % (k, v) for k, v in self.request.headers.items()
# if k.lower().startswith("x-appengine-")]
#logging.info(", ".join(headers))

try:
my_run(self.request.body)
except deferred.PermanentTaskFailure, e:
# if you need the stacktrace mail it to your developer email adress
# use ERROR: no logging of filenames
logging.error("Permanent failure attempting to execute task")

application = webapp.WSGIApplication([(".*", TaskHandler)])

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()
------------------------------------------------------------------------

Nick Johnson (Google)

unread,
May 14, 2010, 2:15:24 PM5/14/10
to google-a...@googlegroups.com
On Wed, May 12, 2010 at 7:07 AM, djidjadji <djid...@gmail.com> wrote:
2010/5/12 djidjadji <djid...@gmail.com>:
> If you want to prevent your client to download your code with the
> method Nick describes just choose some random URLs for the remote_api
> and the deferred handler
>

The problem is that these random URLs are visible in the logs.

The only solution is to prevent the use of eval in deferred calls.

Actually, a better solution is to simply not enable both remote_api and deferred if you are providing your app as a service and do not want it to be possible for users to download the source.

Alternately, you could instead patch remote_api to restrict the APIs it can access - simply disabling remote access to the task queue would be sufficient to prevent my hack from working.

-Nick Johnson
 



--
Nick Johnson, Developer Programs Engineer, App Engine Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number: 368047
Google Ireland Ltd. :: Registered in Dublin, Ireland, Registration Number: 368047
Reply all
Reply to author
Forward
0 new messages