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!
Related
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.
I am attempting to gain user input from a html file and pass it into a function that is located in another python file within the same directory.
The user should input their username and password into the html webpage and the inputs will be passed into another a python file to run numerous validation functions.
Some help or guidance would be much appreciated :)
Thank you
form.html file
<form action="{{ url_for("gfg")}}" method="post">
<label for="username">username:</label>
<input type="text" id="username" name="username" placeholder="username">
<label for="password">password:</label>
<input type="text" id="password" name="password" placeholder="password">
<button type="submit">Login</button>
app.py file
# importing Flask and other modules
from flask import Flask, request, render_template
# Flask constructor
app = Flask(__name__)
# A decorator used to tell the application
# which URL is associated function
#app.route('/', methods=["GET", "POST"])
def gfg():
if request.method == "POST":
# getting input with name = fname in HTML form
username = request.form.get("username")
# getting input with name = lname in HTML form
password = request.form.get("password")
return username + password
return render_template("form.html")
if __name__ == '__main__':
app.run()
main python file (where functions are located)
def main():
username = app.gfg()[0]
password = app.gfg()[1]
TestLogin(username, password)
if __name__ == "__main__":
main()
You need to use the request context.
RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that
needed an active HTTP request. Consult the documentation on testing
for information about how to avoid this problem.
[...]
with app.test_request_context(
'/url/', data={'format': 'short'}):
username = app.gfg()[0]
password = app.gfg()[1]
TestLogin(username, password)
[...]
You can have a look at the docs
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
I'm completely new to flask, and really am completely lost with how to approach this. I've looked into other SO questions but I can't seem to get this working regardless.
I have a form as such:
<form class="teamSelection" method="POST" action="/submitted">
<select class="teamForm" id="teamDropdownSelector" type="text" name="teamDropdown" placeholder="Select A Team">
<option disabled selected>Select a game</option>
<option id="WatfordVSManchester Utd" value="">Watford VS Manchester Utd</option>
</select>
<input class="btn" type="submit" value="submit">
</form>
and my flask as so:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted")
def hello():
return "hello world"
The goal is to take the content of the selected/submitted dropdown item, pass this to the flask file where I then use the team names to scrape information about the match. However at the moment I can't even seem to get the POST of the form to work and am at a complete loss. I appreciate this is a pretty vague and open-ended question, but I seriously don't know how else to figure this out.
Should I instead use jquery to detect when the dropdown has changed and use AJAX to send a POST to somehow call the script and pass the values into it?
Any help would be greatly appreciated.
EDIT
I thought I put this in the original post, but must have forgot.
I am currently running an apache localhost server, and am working with flask via pycharm. All I've done at the moment is install the flask package in pycharm, and haven't set any of it up like I've seen in some tutorials do when running from the command line. I assumed this step wasn't necessary, as I already have a server up and running with apache?
When it comes to backend stuff like this I really have no idea, so apologies if that's a stupid assumption.
I've changed the flask to:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
with open("newTest.csv", mode="w+") as file:
fileWriter = csv.writer(file)
fileWriter.writerow(['Time', 'HomeTeam', 'AwayTeam'])
file.close()
The reason being as I can see if this script is actually being called, if it is it will make a new csv file called newTest. After running the webpage and submitting no new csv file appears, so this script isn't being run, meaning it's likely due to me not configuring flask correctly?/The assumption that apache was enough was incorrect?
You have just to tell the flask method to accept POST request and to read parameters from the request
Example:
from flask import Flask, request
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
myvariable = request.form.get("teamDropdown")
... your code ...
return "hello world"
So, your question is not about flask, but about fopen - you have to add a full file path including directory path script_dir = path.dirname(path.abspath(__file__)).
Flask script (modified for launching in my local copy of project):
from flask import Flask, render_template, request
import csv
from os import path
app = Flask(__name__)
script_dir = path.dirname(path.abspath(__file__))
#app.route ("/")
def index():
return render_template("index.html")
#app.route("/submitted", methods=["GET", "POST"])
def hello():
if request.method == "GET":
return render_template("index.html")
filefullpath = script_dir + '//newTest.csv'
with open(filefullpath, mode="w+") as file:
fileWriter = csv.writer(file)
fileWriter.writerow(['Time', 'HomeTeam', 'AwayTeam'])
file.close()
return "hello world"
index.html (in folder "/templates")
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
Test
<br>
<form class="teamSelection" method="POST" action="/submitted">
<select class="teamForm" id="teamDropdownSelector" type="text" name="teamDropdown" placeholder="Select A Team">
<option disabled selected>Select a game</option>
<option id="WatfordVSManchester Utd" value="">Watford VS Manchester Utd</option>
</select>
<input class="btn" type="submit" value="submit">
</form>
</body>
</html>
Modify your code as:
from flask import Flask
app = Flask(__name__)
#app.route("/submitted", methods=['POST'])
def hello():
return request.form['teamDropdown']
Please let me know if that helps.
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