How to protect a Google App Engine app with a password? - python

How would you implement simple password protection on a Google App Engine application? No users authentication, just simple requirement to enter a password in order to open specific page. The other requirement is that the target page should not be displayed if its URL is entered directly.
I'm looking for a solution using Python.

If you're protecting a single page and need no session persistence.
class MainPage(webapp.RequestHandler):
def post(self):
if self.request.get('user') == 'admin' and self.request.get('pass') == 'soopersecure':
self.response.out.write('authorized');
else:
self.response.out.write("""
<form method="post">
<input type="text" name="user"/>
<input type="password" name="pass"/>
<input type="submit" value="login"/>
</form>""")
Otherwise you could hash the username + salt and hand it to user as a session ID in a cookie and store that session ID into the datastore. Much simpler to use Google accounts though.
http://code.google.com/appengine/docs/python/gettingstarted/usingusers.html

If you want to restrict access for the entire app, use URL handler with "login" setting
Check - User and Administrator Login

Related

Flask form validation - CSRF token middleware

I have an html form, and I would like to insure that all submissions come from my website. I think I have seen people using a key for this (I believe this happens in Django?), and might have some ideas on how to go with that. Is there any standard way to do this in Flask?
Edit:
Now I know I'm talking about CSRF token middleware. Again, is there any standard way of doing this in Flask? How can I store the key on the server side?
In flask you can do CSRF protection using Flask-SeaSurf.There are other methods also but it is straight forward.
To start Just do pip install flask-seasurf and you are ready
import Flask
from flask_seasurf import SeaSurf
app = Flask(__name__)
csrf = SeaSurf(app)
<form method="POST">
...
<input type="hidden" name="_csrf_token" value="{{ csrf_token() }}">
</form>
#csrf.exempt
#app.route('/exempt_view', methods=['POST'])
def exempt_view():
'''This view is exempted from CSRF validation.'''
return 'foobar'
For more information you can visit official website
Please mark this as answer if this solves you problem.

The login form doesn't work at all (using flask) in cs50 web pset 1

I'm trying to create a login form that checks the existence of an account via a username and a password i've tried some stuff but don't seem to be able to get it to work
<form id="signupform" action="{{url_for ('login') }}" method="post">
<div class="input-group input-group-lg">
<input type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon1" name="username" >
</div>
<div class="input-group input-group-lg">
<input type="password" class="form-control" placeholder="Password (8 chars min)" aria-describedby="sizing-addon1" name="password" " >
</div>
<small id="emailHelp" class="form-text text-muted">
We'll never share your info with anyone else.<br>
No account? sign up here!
</small>
<button type="button" class="btn btn-primary">Login</button>
</form>
this is the the form ^^
import os
from flask import Flask, session ,render_template , request
from flask_session import Session
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
app = Flask(__name__)
# Check for environment variable
if not os.getenv("DATABASE_URL"):
raise RuntimeError("DATABASE_URL is not set")
# Configure session to use filesystem
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
# Set up database
engine = create_engine(os.getenv("DATABASE_URL"))
db = scoped_session(sessionmaker(bind=engine))
#app.route("/")
def index():
return render_template("login.html")
#app.route("/home" , methods=["POST"])
def login():
# request username and password
username=request.form.get("username")
password=request.form.get("password")
#check if account exists
account= db.execute("SELECT * FROM users WHERE username = :username AND password = :password ",
{"username":username , "password":password }).fetchone()
if account is None:
return render_template("loginerror.html")
else:
return render_template("homepage.html")
and this is the flask app^^
the database is also linked correctly so idk
i'm so lost, any help is really appreciated
The problem is here <button type="button" class="btn btn-primary">Login</button>
. From MDN button element doc:
type
The default behavior of the button. Possible values are:
submit: The button submits the form data to the server. This is the default if the attribute is not specified for buttons
associated with a , or if the attribute is an empty or invalid
value.
reset: The button resets all the controls to their initial values, like . (This behavior tends to annoy
users.)
button: The button has no default behavior, and does nothing when pressed by default. It can have client-side scripts listen to the
element's events, which are triggered when the events occur.
You didn't specified the error you got (and you should have to), but I'm pretty sure that the form you made is correct (there's a trailling quotation mark at the end of your password field)
There is no methods=["POST","GET"]) in your #app.route("/home" , methods=["POST"]) snippet. Currently, you code is posting his result but cannot get the page back. When you are using post, you are sending information to the server, but it's NOT a "GET" request which mean it won't change your URL or search for a new one. You should implements a function that check if you are logged in and if so, do a "window.location.href = myserver.com/home" (in js).
Also, I suggest you two things. First, use a already made login engine like flask-login you will save time. Also, if you don't need to access the model by another procces simultaneously, use the flask-sqlalchemy library. It's a nice wrapper that reduce the code you have to write

Python CGI: Persistence with Session Keys

Total novice here!
I am trying to create a simple web interface for SUSE Manager using it's API. The issue I am encountering isn't really with SUSE Manager, but with CGI. Right now, I simply want to accomplish two things at the moment:
1) Log in screen where the user enters in their username and password for SUSE Manager.
2) After logging in, the user has multiple links for running different API calls for the application.
In the index.html file, I have the forms to log in and submit the username and password values to "auth.py".
<html>
<title>Login</title>a/
<body>
<b>SuSE Manager Tools</b><br /><br />
<form action="/cgi-bin/auth.py" method="POST">
Username: <input type="text" name="username">
Password: <input type="password" name="password"><br /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>
The "auth.py" then authenticates with the server and generates a session key. This key will be used for all authentication going forward when running API procedure calls.
#!/usr/bin/python2.7
import cgi, cgitb, xmlrpclib, os
print "Content-type: text/html\r\n\r\n"
cgitb.enable()
form = cgi.FieldStorage()
MANAGER_URL = "http://susemanager"
MANAGER_LOGIN = form.getvalue('username')
MANAGER_PASSWORD = form.getvalue('password')
client = xmlrpclib.Server(MANAGER_URL, verbose=0)
key = client.auth.login(MANAGER_LOGIN, MANAGER_PASSWORD)
Now I have a bunch of individual '.py' files that run these procedure calls. I would at this point present the user with several links to run specified procedures. My question is, what is a good method of passing these session keys to the .py files so that they can authenticate against the server?
Perhaps I'm going about this all wrong? Perhaps CGI isn't the answer. There seems to be a lot of hub bub around CGI not being the best choice these days and that it has become outdated. Maybe I should be looking into WSGI or do you think for something so simple, CGI remains the better option?
Thanks folks.
Using Flask and the built-in 'session' module, I was able to get this done like so:
from flask import Flask, render_template, session, request, redirect, url_for
import xmlrpclib
app = Flask(__name__)
#app.route('/', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
session['user'] = request.form['username']
session['passwd'] = request.form['password']
return redirect(url_for('menu'))
return render_template('login.html')
#app.route('/menu/')
def menu():
user = session.get('user', None)
passwd = session.get('passwd', None)
Thanks for the help!

can't get post parameter in multipart form

I have the following form shown in a modal of a bootstrap page
the aim is to upload a file with a hidden id
the application is based on Google App Engine, Python/Webapp2
<form action="someUrl" role="form" method="POST" enctype="multipart/form-data">
<input type="hidden" name="entityId" value="{{datastoreEntity.key.id()}}"/>
<input name="importFile" type="file" multiple>
<input type="text" class="form-control" readonly>
<input type="submit" name="submit" value="Import">
</form>
the problem is in the related RequestHandler (server side) where I can retrieve the file with
raw_file = self.request.POST.multi['importFile'].file
But I can't get the id (which is correctly generated by Jinja2 - checked in the page source). I have already tried with
self.request.get('entityId')
self.request.POST['entityId']
self.request.POST.multi['entityId']
I can't reproduce the problem as you relate it in the simplest of ways. I've copied that template into form.html, direct / to MainHandler, and net of the usual preparations (imports, jinja_environment with a FileLoader in the current dir, etc, I have):
class It(ndb.Model):
name = ndb.StringProperty()
class MainHandler(webapp2.RequestHandler):
def get(self):
dse = It(name="Willy")
dsek = dse.put()
datastoreEntity = dsek.get()
template = jinja_environment.get_template('form.html')
self.response.write(template.render(dict(
datastoreEntity=datastoreEntity,
)))
def post(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write(self.request.get('entityId'))
Visiting /, picking a file, and clicking the Import button, I see on my browser: 5066549580791808 -- which seems to be a typical datastore entity ID, as desired.
Please "interpolate" between this toy super-simplified version, and the no doubt much more complex things you're trying to do, and edit your Q to show us the very simplest way you can reproduce your problem, thanks!
Uploading via file inputs in App Engine requires that the app use a path that's obtained from the blobstore API. The doc for that is here. So you probably want to do something like
upload_url = blobstore.create_upload_url('/someUrl')
and then inject that into your template so that the form can use it
<form action="{{upload_url}}" ...
Once the file upload is complete, blobstore will redirect to /someUrl, where you process the rest of the form, including .file.

Forgotten password implementation in Django

I am trying to implement a forgot password functionality in my django application. I have given a seperate forgottenPassword.html, where user can give his email id ; and if that email is registered(found in database) , corresponding password of that email is fetched and sent to his email id.This is what i am trying to achieve. Being a Django newbie i am stuck with the implementation. This is my forgottenPassword.html
<form name="forgotPassword" method="POST" id="myFormid" action="http://10.1.0.90:8080/forgotPassword/">
<div style="float:center;width:100%;">
Enter your E-mail ID</label><br/> <input type="text" name="email" size="25" />
<input type="submit" value="Submit" />
</div>
</form >
my method in views.py is
def forgotPassword(request):
if request.POST:
email=request.POST.get("email")
print email
user = UniversityDetails.objects.filter(email=email)
print user
if(not user):
print "No user"
return render_to_response("forgotPassword.html")
else:
???????????????
return render_to_response("passwordRecovery.html")
return render_to_response('forgotPassword.html')
Here, what i try to achieve is to pass the email id entered in forgottenPassword.html and save it in a variable 'email'. After that fetch all the objects with that email from database. and to filter password from it. I guess the part where i put ???? should be filled with a query to fetch the password corresponding to that email id. Can somebody help me to do this.
There is (by design) no way to do this. You cannot get the password for a user, because it is only stored in the database as a secure hash, and there is no way of reversing that hash.
However, Django does provide a built-in reset password implementation in contrib.auth - see the documentation.
rv_k, I just want to say I've recommended you look at the django.contrib.auth instead of your current system because you are storing passwords as plaintext.
That said, to answer your question, you've already pulled your UniversityDetails query matching the email. Assuming there's only 1 email per "user", use a get query instead.
user = UniversityDetails.objects.get(email=email)
send_mail("Your PW", user.password, "admin#example.com", [email])

Categories