I read many tutorial about django testing but I don't know how can I test for function insde resource , for example this User resource with signin function and obj_create. I really appreciate any helps because I can not figure out how to test them. k thanks.
class UserResource(ModelResource):
school = fields.ToOneField('frittie.app.api.api.LocationResource', 'user')
class Meta:
queryset = UserProfile.objects.all()
resource_name = 'User'
allowed_methods = ['get','post']
serializer = Serializer(formats=['json', 'plist'])
authorization= Authorization()
#models.signals.post_save.connect(create_api_key, sender=User)
#fields = ['username', 'email']
def obj_create(self, bundle, request=None, **kwargs):
if not request.method == "POST":
raise BadRequest('Object not found or not allowed to create a new one.')
username, email, password = bundle.data['username'], bundle.data['password'], bundle.data['password'],
try:
bundle.obj = User.objects.create_user(username, email, password)
except IntegrityError:
raise BadRequest('That username already exists')
return bundle
def signin(self, request, **kwargs):
self.method_check(request, allowed=['post'])
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return self.create_response(request, {'success': True})
else:
# Return a 'disabled account' error message
return self.create_response(request, {'success': False})
else:
# Return an 'invalid login' error message.
return self.create_response(request, {'success': False})
Tastypie has a descent testing documentation - ResourceTestCase API Reference
Related
I am building a simple authentication page that uses Flask and Flask SQLAlchemy deployed on Heroku with PostgreSQL.
I was able to register users but was unable to log in.
Code for Log in:
`
#indexbp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
flash("You have already logged in!", 'success')
return redirect('/')
form = LoginForm()
if form.validate_on_submit():
try:
user = User.query.filter_by(username=form.username.data).first()
if bcrypt.check_password_hash(user.hashed_password, form.password.data):
login_user(user)
flash('You are logged in!', 'success')
return redirect('/')
except AttributeError:
db.session.rollback()
flash('Wrong username, password or email. Please try again!', 'info')
return redirect('/login')
except Exception as e:
print(e)
db.session.rollback()
flash('Something went wrong inside our systems, please try again later. If this problem persists, please contact our admin team.', 'danger')
return redirect('/login')
return render_template('login.html', form=form)
`
Code for Register:
`
#indexbp.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
flash("You have already logged in!", 'success')
return redirect('/')
form = RegisterForm()
if form.validate_on_submit():
try:
new_user = User(username=form.username.data, hashed_password=bcrypt.generate_password_hash(form.password.data), user_id=str(uuid.uuid1()))
db.session.add(new_user)
db.session.commit()
return redirect('/login')
except Exception as e:
print(str(e))
db.session.rollback()
flash('Something went wrong inside our systems, please try again later. If this problem persists, please contact our admin team.', 'danger')
return redirect('/register')
return render_template('register.html', form=form)
`
User table:
`
#User table
class User(db.Model, UserMixin):
id = db.Column(db.Integer(), primary_key=True, unique=True, nullable=False)
username = db.Column(db.String(), unique=True, nullable=False)
hashed_password = db.Column(db.String(), unique=False, nullable=False)
user_id = db.Column(db.String(), unique=True, nullable=False)
`
Flask Configs:
`
app.config['SQLALCHEMY_DATABASE_URI'] = "link-to-database-provided-by-heroku"
app.config['SECRET_KEY'] = "g3AbKqKhxhCACvFNlNgLv802LUBwXQKr4X4Z9J9d"
`
I have tried to migrate the database, rechecking it multiple times.
I have also attempted to run it locally but only registering works.
I installed psycopg2 as well as reconfiguring the User table.
Problem was Flask-Bcrypt not working properly. Changed my hashing function to md5 and it worked.
I am in the process of creating a login system.
I use python flask and as database the Prostgresql.
I think I just store the hash value wrong.
I have saved it as vachar 255 so far
My code:
from flask import Flask, render_template, redirect, request, url_for, session
from flask_sqlalchemy import SQLAlchemy
import bcrypt
import psycopg2
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:PostGreSQL_13#localhost/test'
sql = SQLAlchemy(app)
#app.route('/')
def home():
return render_template("home.html")
#app.route('/register', methods=["GET","POST"])
def register():
if request.method == "GET":
return render_template("register.html")
else:
name = request.form['name']
email = request.form['email']
password = request.form['password'].encode('utf-8')
hash_password = bcrypt.hashpw(password, bcrypt.gensalt())
t_host = 'localhost'
t_port = "5432"
t_dbname = "test"
t_user = "postgres"
t_pw = "password"
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
db_cursor = db_conn.cursor()
db_cursor.execute("INSERT INTO users (UserName,UserEmail,UserPassword) VALUES (%s,%s,%s)",(name,email,hash_password,))
db_conn.commit()
session['name'] = name
session['email'] = email
return redirect(url_for("home"))
#app.route('/login', methods=["GET","POST"])
def login():
if request.method == "POST":
email = request.form['email']
password = request.form['password'].encode('utf-8')
t_host = 'localhost'
t_port = "5432"
t_dbname = "test"
t_user = "postgres"
t_pw = "password"
db_conn = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
db_cursor = db_conn.cursor()
db_cursor.execute("SELECT username, useremail, userpassword FROM users WHERE useremail=%s",(email,))
user = db_cursor.fetchone()
db_conn.close()
if len(user) > 0:
name = user[0]
if bcrypt.hashpw(password, user[2].encode('utf-8')) == user[2].encode('utf-8'):
session['name'] = user[0]
session['email'] = user[1]
return render_template("home.html")
else:
return "Versuch es doch Nochmal"
else:
return render_template("login.html")
#app.route('/logout')
def logout():
session.clear()
return render_template("home.html")
if __name__ == '__main__':
app.secret_key = '012#!ApaAjaBoleh)(*^%'
app.run(debug=True)
the procedure I got from the Youtube video. see attachment.
I need a login system and this was recommended to me, it works pretty good.
The last one has to work somehow and if it works I would be very happy.
Can anyone tell me what I'm doing wrong or if my appendix with the database is right or wrong?
I know nothing about this language you're using, but any bcrypt implementation will output a string similar to:
$2a$12$ieXy2Rj/TEGqVRx0JihGFesujNFCdmlQWpUaTNvwQ0XuB3lzOcTWK
Yes, you should store that varchar string in your database.
i am building a REST api with JWT authorization abstracting the user model. So these are some of the functions I define in my user model definition:
def save_to_db(self):
db.session.add(self)
db.session.commit()
def update_db(self):
db.session.commit()
def delete_from_db(self):
db.session.delete(self)
db.session.commit()
and these are the methods:
#jwt_required()
def get(self):
user = UserModel.find_by_email(current_identity.email)
if user:
return user.json(), 200
return {'message': 'User not found'}, 400
def post(self):
data = UserRegister.parser.parse_args()
if UserModel.find_by_email(data['email']):
return {"message": "User already exists"}, 400
user = UserModel(**data)
user.save_to_db()
return user.json(), 200
#jwt_required()
def put(self):
user = UserModel.find_by_email(current_identity.email)
if user:
data = UserRegister.parser.parse_args()
try:
user = UserModel(**data)
user.update_db()
return user.json(), 200
except:
return {'message': 'An error ocurred while inserting user data.'}, 400
Everything is working except the PUT method. It does not store the actual value in the database, I am wondering why.
there is something fundamentally wrong with my code. These are my
tornado handlers with basic authentication and jinja2 as template
engine. The following works without the momoko db parts.
class BaseHandler(tornado.web.RequestHandler):
#property
def db(self):
return self.application.db
def get_current_user(self):
return self.get_secure_cookie("user")
class TemplateHandler(BaseHandler):
"""Request handler for writing HTML templates."""
def render(self, template_name, **kwargs):
"""Renders a Jinja2 template."""
kwargs['options'] = options.as_dict()
template = templates.environment.get_template(template_name)
html = template.render(kwargs)
self.write(html)
class AuthLoginHandler(TemplateHandler):
def get(self):
try:
errormessage = self.get_argument("error")
except:
errormessage = ""
self.render("login.html", errormessage = errormessage)
def check_permission(self, password, username):
if username == "admin" and password == "admin":
return True
return False
def post(self):
username = self.get_argument("username", "")
password = self.get_argument("password", "")
auth = self.check_permission(password, username)
if auth:
self.set_current_user(username)
self.redirect(self.get_argument("next", u"/"))
else:
error_msg = u"?error=" + tornado.escape.url_escape("Login incorrect")
self.redirect(u"/auth/login/" + error_msg)
def set_current_user(self, user):
if user:
self.set_secure_cookie("user", tornado.escape.json_encode(user))
else:
self.clear_cookie("user")
class AuthLogoutHandler(TemplateHandler):
def get(self):
self.clear_cookie("user")
self.redirect(self.get_argument("next", "/"))
class MainHandler(TemplateHandler):
#gen.engine
def get(self):
username = tornado.escape.xhtml_escape(self.current_user)
try:
cursor = yield momoko.Op(self.db.execute, 'SELECT * FROM products;')
except Exception as error:
self.write(str(error))
res = 'Query results: '+''.join(str(cursor.fetchall()))
self.render("index.html", username = username, cip = self.request.remote_ip, res = res)
For the logged in client, this code should execute a basic query and then print the result to the defined location ( {{ res }} ) within the jinja template. When I try to start the server, I get this:
line 22, in render
kwargs['options'] = options.as_dict()
AttributeError: 'module' object has no attribute 'as_dict'
We'll need to see your "import" statements to know what's wrong for certain. I suspect you have:
from tornado import options
But you need:
from tornado.options import options
I want to save the client credentials obtained from Drive API. I tried the following code below, it's working well to store credentials but when I'm accessing the data in upload view it's not returning the credential
views.py
from oauth2client.django_orm import Storage
from drv_app.models import CredentialsModel
#authorization of the client by the user
def authorize_application(request):
#setting flow to get permission and code
flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET, OAUTH_SCOPE, REDIRECT_URI, ACCESS_TYPE)
authorize_url = flow.step1_get_authorize_url()
code = request.GET.get('code', '')
if code:
#setting flow step2 to exchage code for access token
credential = flow.step2_exchange(code)
#initialising httplib2 instance and building a DriveAPI service
http = httplib2.Http()
http = credential.authorize(http)
drive_service = build('drive', 'v2', http=http)
user, created = User.objects.get_or_create(username=username, email=email)
#saving credentials to database
if created == True:
storage = Storage(CredentialsModel, 'id', user, 'credential')
storage.put(credential)
return HttpResponseRedirect('/upload/')
else:
return HttpResponseRedirect('/upload/')
else:
return HttpResponseRedirect(authorize_url)
def upload_file(request):
username = request.session['username']
user = User.objects.get(username=username)
storage = Storage(CredentialsModel, 'id', user, 'credential')
credential = storage.get()
http = httplib2.Http()
http = credentials.authorize(http)
drive_service = build('drive', 'v2', http=http)
media_body = MediaFileUpload(FILENAME, mimetype='text/plain', resumable=True)
body = {
'title': 'vishnu_test',
'description': 'A test document',
'mimeType': 'text/plain'
}
file = drive_service.files().insert(body=body, media_body=media_body).execute()
pprint.pprint(file)
return HttpResponse('uploaded')
models.py
from oauth2client.django_orm import FlowField
from oauth2client.django_orm import CredentialsField
class CredentialsModel(models.Model):
id = models.ForeignKey(User, primary_key=True)
credential = CredentialsField()
What I'm doing wrong? Please suggest the necessary improvements.
Replace ForeignKey with OneToOneField in CredentialsModel