gae-init / gae-init Goto Github PK
View Code? Open in Web Editor NEWGoogle App Engine based on Python, Flask, RESTful, Bootstrap and tons of other cool features
Home Page: https://gae-init.appspot.com
License: MIT License
Google App Engine based on Python, Flask, RESTful, Bootstrap and tons of other cool features
Home Page: https://gae-init.appspot.com
License: MIT License
our email & pw auth is pretty much HTTP / HTML form based auth. It's a very common technique, but also very very very insecure when used via http as it sends plain text credentials around.
I think we should tighten this up in a couple of ways:
I probably didn't pay attention before, but why is the User considered to be modified on sign in?
After an accidental format, I had to re-setup my linux machine. Everything worked out of the box except node. I fixed it by replacing node
with nodejs
in run.py
.
:486
of run.py
def check_nodejs():
return bool(spawn.find_executable('nodejs')), 'Node.js', '#nodejs'
Not a major problem, as the Admin should now better... but there is an XSS vulnerability in the current Announcement HTML
field on the Admin Config
form.
To reproduce: run ./run.py -ms
and browse to http://localhost:8080/admin/config/
(if needed login as an administrator). Then provide <script>alert(document.cookie);</script>
in the Announcement HTML
field and hit Update Config
... start enjoying the cookies-in-your-face.
What I would like to know is whether we already have precautions against XSS (see https://www.owasp.org/index.php/Testing_for_Cross_site_scripting for details), for example in support libraries, and how we could turn them on/off as needed on fields. Perhaps we simply need to set a flag somewhere?
Proposal for version 1. Observing other implementations like bootstrap and many of yeoman projects they use dist instead of dst. I can feel that both src and dst are 3 characters but I think what most people use is stronger argument.
I've seen a lot about sign in with OpenId, ¿what about email/password from Google App Business? In these case, I guess the User model is unnecessary, right?
In pull request #47, I've moved the Flask-WTF into main/lib/flask_wtf/
and updated imports to use flask.ext.wtf
. The gae-init/gae-init-babel#9 PR for gae-init-babel proposes a similar move for Flask-Babel.
In the discussion that followed, https://github.com/lipis mentioned:
I remember playing around with the
flask_ext
,flaskext
andflask.ext
and I agree that we have to follow the latest and greatest standards, I'm just too careful with folder structure changes and would prefer to spend some time to check what's best..
To help this assessment, this issue documents my findings.
As I noted in the PRs, http://flask.pocoo.org/docs/extensiondev/#anatomy-of-an-extension shows that the flask.ext.foo
notation can be followed to find the extensions (which in recent incarnations of Flask are all moving towards a more maintainable structure).
The same article shows that the extension folder flask_wtf/
(as it is also named in the original source: https://github.com/lepture/flask-wtf/tree/master/flask_wtf) can sit in our main/lib/
while the flask.ext
does it's magic to resolve imports from flask.ext.wtf
(this seems to be a common pattern for Flask extensions).
Following the code, https://github.com/gae-init/gae-init/blob/master/main/lib/flask/ext/__init__.py explains the flask.ext
strategy to transition away from flaskext.foo
to flask_foo
and in which order the extensions are tried to be imported (when asking for flask.ext.foo
it first tries to import from flask_foo
and if that fails from flaskext.foo
).
Wondering on whether directly importing from flask_foo
might be preferred (instead of using the middleware flask.ext.foo
... perhaps performance?), the http://stackoverflow.com/a/19296731/2315612 answer refers to the fine documentation at http://flask.pocoo.org/docs/extensiondev/#extension-import-transition
Inside the extensions they do use import flask_foo
, but it seems this is to allow re-use of the packages outside the Flask context. And the changes I propose in the PRs do allow the use of both import flask.ext.foo
and import flask_foo
when the extension is located in main/lib/flask_foo
Aiming to be "the easiest way to kick start new applications on Google App Engine using Flask, ..."; I think we should be good citizens and follow the latest Flask extension guidance (see article reference above): using flask.ext.foo
for imports and having the extension folder flask_foo/
inside main/lib/
.
This is more a discussion than a bug, maybe i'm doing it wrong: after a gae-init release and a lot of merging things into projects i like to upgrade things in a clean way.
Usually i would do ./run.py -C
but i notice that the npm
step is very slow. We're talking about > 10 minutes on a very fast internet connection.
If i run npm update
it seems to be even slower.
As i'm not a node guru: is there a way to speed this up?
output here: https://gist.github.com/joernhees/ce47441e0c76337ea6db
i would like to propose to have the indexes for the default gae-init features prefilled in the index.yaml file.
My rational for this is that it just happened to me that as a dev i didn't test all the default features of gae-init first in the dev server before deploying my app, but just the parts i developed myself. In production the userlist and custom login then didn't work because of missing compound indices...
This is a bit developer unfriendly i think, especially for rather trivial apps. Would it hurt to have them prefilled?
Currently i think these are the places where such indices are currently used by default:
For every single doc string removed there should be a separate PR for easier maintenance in the gae-init-docs project.
A macro that allows the generation of radio buttons would be very useful.
This question from StackOverflow needs one more vote to be opened, but until then here is the answer.
There are usually 3 things that you need to do in order to add a 3rd party library into gae-init project.
As an example I will use the Selectize library since I believe is a bit better choice than the requested Bootstrap Tags Input.
In the bower.json
file add the name of the library (or the direct link to the git repo) in the dependencies
section and depending on the library you will have to write which files you need from it described in the exportsOverride
section.
Here is how the bower.json
will look like:
{
"dependencies": {
...
"selectize": "~0"
},
"exportsOverride": {
...
"selectize": {
"js": "dist/js/*",
"less": "dist/less/*.less",
"less/plugins": "dist/less/plugins/*"
}
}
}
Because Selectize libriary has JavaScript and Less files we will have to make sure that they will be included in the build process and used by gae-init.
The JavaScript files are defined in the config.py
:
SCRIPTS = [
('libs', [
...
'ext/js/selectize/selectize.js',
]),
...
To merge the Less files into one single CSS in the end import them in the style.less
like this:
...
@import "../../ext/less/selectize/selectize";
@import "../../ext/less/selectize/selectize.bootstrap3";
@import "../../ext/less/selectize/plugins/remove_button";
...
Finally you will have to execute the ./run.py -s
. Since there were changes in the bower.json
the 3rd party library will be downloaded and copied into the right place.
Just to see it in action you could add a simple input
field somewhere in your template:
<input class="form-control" type="text" value="foo bar">
and run the following code from the console of your browser (as taken from their official examples):
$('.form-control').selectize({
plugins: ['remove_button'],
delimiter: ' ',
persist: false,
create: function(input) {
return {
value: input,
text: input
}
}
});
Here is the final result in action: Selectize gae-init example.
I forgot that I wanted to make that change while breaking stuff.. WDYT?
Even though the robots looks like they are following them.. they most likely not needed for rankings..
http://en.wikipedia.org/wiki/Nofollow#Interpretation_by_the_individual_search_engines
Any thoughts?
https://github.com/gae-init/gae-init/blob/master/main/model/config.py#L40
Is it on purpose that self.feedback_email
has to be sent so that email_authentication works?
/_s/callback/facebook/oauth-authorized/?code=AQCuUVQb_....
'email'
Traceback (most recent call last):
File "lib.zip/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "lib.zip/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "lib.zip/flask_oauth.py", line 434, in decorated
return f(*((data,) + args), **kwargs)
File "/base/data/home/apps/s~lim-life-line/date.377588946281106576/auth.py", line 380, in facebook_authorized
user_db = retrieve_user_from_facebook(me.data)
File "/base/data/home/apps/s~lim-life-line/date.377588946281106576/auth.py", line 406, in retrieve_user_from_facebook
response['email'],
KeyError: 'email'
(config.py:17)
Since the whole thing is broken down now in separate files and even in the admin console there is separate link for OAuth maybe it makes sense to include all of them here and not maintaining both files as it's not actually adding any overhead AFAIK...
What do you think?!
Everything should be sorted by name except for the oauth.html
template where the providers Google, Facebook and Twitter always should be first and the rest in alphabetical order.
HTML validator requires maximum 3 decimal digits for the seconds. moement.js with python isoformat() produce more.
According to https://developers.google.com/appengine/docs/python/#Python_The_environment the minor version of CURRENT_VERSION_ID is always "1" on the development web server.
However, I'm seeing stuff like 423594672088649939 using version 1.8.9 of the SDK (on a Xubuntu virtual machine), which I'm afraid sometimes triggers an exception in config.py
when converting to long
in the CURRENT_VERSION_TIMESTAMP; and/or resulting in CURRENT_VERSION_DATE being way out in the past or the future (that is: on the development web server).
Is this something in my development VM, or are others also seeing the CURRENT_VERSION_ID.split('.')[1]
unequal to "1" on their local development web server testing (using SDK 1.8.9)?
would anyone else find it convenient to have the possibility to specify which methods the standard auth decorators become active for?
I often have the case where it's ok to view (GET
) a page for everyone but modification (POST
) requires login or admin...
If someone else finds this interesting i'd rewrite the decorators similarly to django's view function decorators in a backwards compatible way, so you can still use @login_required
without args, but you could also use @login_required(methods=['POST'])
to only require a login for POST
requests.
Was trying to run through the tutorial and when adding the main/contact.py code there is a dependency on wtf, when in the newest release apparently you have to use wtforms.
class ContactUpdateForm(wtf.Form):
name = wtf.StringField('Name', [wtf.validators.required()])
email = wtf.StringField('Email', [wtf.validators.optional(), wtf.validators.email()])
phone = wtf.StringField('Phone', [wtf.validators.optional()])
address = wtf.TextAreaField('Address', [wtf.validators.optional()])
should become
import wtforms
class ContactUpdateForm(wtf.Form):
name = wtforms.StringField('Name', [wtforms.validators.required()])
email = wtforms.StringField('Email', [wtforms.validators.optional(), wtforms.validators.email()])
phone = wtforms.StringField('Phone', [wtforms.validators.optional()])
address = wtforms.TextAreaField('Address', [wtforms.validators.optional()])
Interestingly, we still need to inherit wtf.Form in order to get the validate_on_submit() functionality.
When updating a gae-init based project to appspot.com, using for example:
appcfg.py update main --oauth2
Then four warnings (or at least notifications) are shown in the log:
...
Could not guess mimetype for static/font/fontawesome-webfont.ttf. Using application/octet-stream.
Could not guess mimetype for static/font/glyphicons-halflings-regular.ttf. Using application/octet-stream.
Could not guess mimetype for static/font/fontawesome-webfont.ttf. Using application/octet-stream.
Could not guess mimetype for static/font/glyphicons-halflings-regular.ttf. Using application/octet-stream.
...
Note that these 4 lines are about 2 files, namely the two .ttf
files found in main/static/font/
and apparently defaulting to assume the "application/octet-stream" mime type for them when serving.
Whether right or wrong... I lack the knowledge; so Google to the rescue and I found: https://code.google.com/p/googleappengine/issues/detail?id=6183 in which the "Jul 17, 2013" comment provides some interesting clue. There might be some value in trying to tell GAE they are of the "font/ttf" mime type. It hints at a possible gzip or deflate compression and notes that "TTF fonts are great candidates for gzip compression, which saves about 20% on the size of my fonts. This results in decreased load times for users and reduced bandwidth for app owners."
Thus I tried in app.yaml
the following:
...
- url: /p/font/(.*\.(ttf))
static_files: static/font/\1
upload: static/font/(.*\.(ttf))
mime_type: font/ttf
expiration: 1000d
- url: /p/font/(.*\.(ttf))
static_dir: static/font/\1
expiration: 1000d
...
And that made the warnings go away, while still only "Cloning 13 static files" (I was afraid that there might be a duplication on the upload... but there isn't?) and in testing the site I didn't spot a difference in behaviour / look-and-feel.
However, I'm not sure whether the above is better or not... I like the cleaner log when updating to appspot.com and would assume that removing guesswork is better; but whether the compression is really better (as hinted)?
Any gi with an opinion on this (and/or can we measure / see the possible gain)?
There are a lot of changes and bunch of new features. Is there anything that we have to change in the code?
http://blog.getbootstrap.com/2014/01/30/bootstrap-3-1-0-released/
Switch to standard **kwargs
or **kws
, where I am in favour of the first one since its widely used.
And it's actually not really your numeric ID as it used to be where you could link back to the actual user like this: facebook.com/112233445566
Well, I have a bit more complicated structure for my work project and I am facing some trouble with the imports of the new model.
My major difference is that I keep controllers, lib and models under a dir called server so my models can be found under main/server/model
instead of main/model
.
In config.py
I manage to do successfully from server import model
but when I go for example to main/server/model/user.py
and I try to do from server import model
I get an error model cannot be found, instead if I do from server.model import Base
everything works normal. Like this though I have to define everytime all the classes I want imported. Any ideas anyone? I have struggled a bit with paths in appengine_config.py
but no luck :(
Because you might got the code without using git, but it is needed for the Bower to work.
In get_next_url
If you update the status of a user to be an admin and hit "Update" you're sent back to the user list, where it still shows the user not to be an admin.
Once you reload the page the display is correct.
Maybe could be solved with an ancestor query?
New python executable in temp\venv\Scripts\python.exe
Installing setuptools, pip...done.
pip install -q -r requirements.txt
Traceback (most recent call last):
File "C:\Developer\Projects\WebDevelopement\temp\venv\lib\site.py", line 703, in <module>
main()
File "C:\Developer\Projects\WebDevelopement\temp\venv\lib\site.py", line 683, in main
paths_in_sys = addsitepackages(paths_in_sys)
File "C:\Developer\Projects\WebDevelopement\temp\venv\lib\site.py", line 282, in addsitepackages
addsitedir(sitedir, known_paths)
File "C:\Developer\Projects\WebDevelopement\temp\venv\lib\site.py", line 204, in addsitedir
addpackage(sitedir, name, known_paths)
File "C:\Developer\Projects\WebDevelopement\temp\venv\lib\site.py", line 173, in addpackage
exec(line)
File "<string>", line 1, in <module>
File "C:\google-cloud-sdk\bin\dev_appserver.py", line 10, in <module>
import bootstrapping.bootstrapping as bootstrapping
File "C:\google-cloud-sdk\bin\bootstrapping\bootstrapping.py", line 21, in <module>
from googlecloudsdk.core.credentials import store as c_store
File "C:\google-cloud-sdk\bin\bootstrapping\..\..\lib\googlecloudsdk\core\credentials\store.py", line 18, in <module>
from googlecloudsdk.core.credentials import flow
File "C:\google-cloud-sdk\bin\bootstrapping\..\..\lib\googlecloudsdk\core\credentials\flow.py", line 13, in <module>
from oauth2client import tools
File "C:\google-cloud-sdk\bin\bootstrapping\..\..\lib\oauth2client\tools.py", line 58, in <module>
argparser = argparse.ArgumentParser(add_help=False)
File "C:\google-cloud-sdk\bin\bootstrapping\..\..\lib\argparse\__init__.py", line 1585, in __init__
prog = _os.path.basename(_sys.argv[0])
AttributeError: 'module' object has no attribute 'argv'
Could you add REST API?
I believe that def auth
serves more than one purposes. Would it make more sense if it was separate, like def auth_signin
, def auth_signup
?
there are always appear the error by follow tutorial
[22:43:36] --------DONE ----------------------------------------------
INFO 2014-09-18 14:43:38,541 devappserver2.py:725] Skipping SDK update check.
WARNING 2014-09-18 14:43:38,546 api_server.py:383] Could not initialize images API; you are likely missing the Python "PIL" module.
INFO 2014-09-18 14:43:38,580 api_server.py:171] Starting API server at: http://localhost:49195
INFO 2014-09-18 14:43:38,609 dispatcher.py:183] Starting module "default" running at: http://127.0.0.1:8080
INFO 2014-09-18 14:43:38,639 admin_server.py:117] Starting admin server at: http://localhost:8081
ERROR 2014-09-18 14:43:40,766 wsgi.py:262]
Traceback (most recent call last):
File "/Users/Alpha/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 239, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/Users/Alpha/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 298, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/Users/Alpha/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 84, in LoadObject
obj = import(path[0])
File "/Users/Alpha/Downloads/phonebook/main/main.py", line 5, in
from flask.ext import wtf
ImportError: No module named flask.ext
INFO 2014-09-18 14:43:40,776 module.py:652] default: "GET /_ah/warmup HTTP/1.1" 500 -
hi, I've been learning flask on gae development these days, and I found this repo is amazing, but I got confused by these codes below:
_PROPERITES={
key,
id,
version
}
and all like above.
what's these mean? any reference on flask docs?
tks a lot
When I flush the local datastore with a ./run.py -f
it removes the ./temp/datastore/
folder (and all files inside) as expected. It however leaves the ./temp/
folder, which to my knowledge is not used for other purposes. Is this as designed (perhaps used in another derived gae-init-*
project), or could we simply add a remove_dir(DIR_TEMP)
to run_flush
in run.py
?
Fellow programmers,
I am creating this issue to put down some of my thoughts about the front end solutions of gae-init and hear back your feedback and suggestions.
My suggestion is that everything that has to do with the front end should be moved under /static
directory including node_modules
, bower_components
, bower.json
, package.json
and Gruntfile.coffee
since they affect files from static and below.
Building the front end should be completely taken care of from Gruntfile
and run.py
should be responsible only to take care of the server.
If we set it up like this we will be able to combine the powehouse back end of gae-init with any front end generator out there. Most of the generators come with their custom Gruntfile
so in most cases we don't even have to configure that.
I am aware that its not a small request, since a lot of things need to be tested and some things might break, but providing the flexibility for any front end environment like angular, backbone or even webapp-skeleton without much hassle, will also provide a boost in the user base of gae-init.
As said in the beginning, food for thought.
Cheers.
That was a long wish that I had and unfortunatelly will break the backwards compatibility but it's for a greater good!
[18:29:31] ---CLEAN ALL ----------------------------------------------
Traceback (most recent call last):
File ".\run.py", line 624, in <module>
run()
File ".\run.py", line 599, in run
run_clean_all()
File ".\run.py", line 511, in run_clean_all
remove_file_dir(DIR_NODE_MODULES)
File ".\run.py", line 134, in remove_file_dir
shutil.rmtree(file_dir)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 244, in rmtree
rmtree(fullname, ignore_errors, onerror)
File "C:\Python27\lib\shutil.py", line 249, in rmtree
onerror(os.remove, fullname, sys.exc_info())
File "C:\Python27\lib\shutil.py", line 247, in rmtree
os.remove(fullname)
WindowsError: [Error 3] The system cannot find the path specified: 'node_modules\\less\\node_modules\\request\\node_modu
les\\lodash.merge\\node_modules\\lodash._basecreatecallback\\node_modules\\lodash.bind\\node_modules\\lodash._createwrap
per\\node_modules\\lodash._basebind\\node_modules\\lodash._basecreate'
PS C:\Developer\Projects\WebDevelopement>
Consider the case where I sign in at gae-init with my Google account. I changed my mind and I want to sign in with my corporate account.
I hit the sign out button and trying to sign in again, but the service logs me in with my existing running session.
The expected behavior would be to give you the option if you want to change the account you want to sign in.
When I click View in JSON on https://gae-init.appspot.com/ then it returns:
{
"error_class": "NotFound",
"error_code": 404,
"error_message": "Not Found",
"error_name": "not-found",
"status": "error"
}
From the framework's perspective of view, it's correct. But as a new user who wants to explore the power of "gae-init", it is a bad user experience.
Currently missing a release/tag for "Version 0.9.0 - 2013-10-20" as listed in the CHANGESET.md
file, at https://github.com/gae-init/gae-init/releases
I used
./run.py -m
in order to create the minified output of JavaScript for the deployed version. I ended up with a file containing only ;
The bug came from my ignorance where I had defined twice a path in my SCRIPT_MODULES in config.py.
You can reproduce
'scripts': [ 'src/script/common/util.coffee', 'src/script/common/service.coffee', 'src/script/common/upload.coffee', # Add this duplicate entry below 'src/script/site/app.coffee', 'src/script/site/app.coffee', .... ]
The case is that minifier also didn't spit any message. I know I should have been more careful but when the list gets bigger and things get copy pasted .. mistakes happen.
This might be a good entry point to bring up my <3 for Grunt one more time. Since Grunt is used for monitoring changes in files why not use it for building them also. This is going to save us one terminal window ;). The run script I suggest to be used for starting stopping the App Engine Server and deploying the app.
@lipis, @mdxs, @gmist, Where do you stand on this one? I think I will give it a finger in the weekend :)
In util.py, line 197:
def update_query_argument(name, value=None, ignore=[], list=False):
...
This is a mistake or not?
appengine now supports golang (in addition to python, java and php)
would be nice if gae-init would support that runtime
since it is a good lunguage and its at very mature state right now
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.