How to check if a child in firebase database exists using Django? - django

the following code throws attribute error
''Database' object has no attribute 'exists''.
from django.shortcuts import render
from django.views import View
from django.views.decorators.cache import cache_page
from django.views.decorators.csrf import csrf_protect
import pyrebase
from django.contrib import auth
import json
import requests
from . import services
from .models import Product
authe = services.firebase_key().auth()
database = services.firebase_key().database()
def Login(request):
return render(request, "Login.html")
def postsign(request):
data = services.get_products()
print(data)
context = {'data': data}
number = request.POST.get('number')
password = request.POST.get("password")
if database.child("users").child(number).exists():
user = database.child("users").child(number).get().val()
if user['number'] == number:
if user['password'] == password:
return render(request,"Welcome.html",context)
I need to check if the number exists in the database or not since I want the existing users to log in using numbers and passwords.

Check if child exist in Python using Pyrebase, should be something similar, see official docs here
if not database.child('users').shallow().get().val():
print("users does not exist")
else:
print("users exist")

You can try below.
if database.child('users').child(number).shallow().get().val():
print("user exists")
else:
print("user does not exist")

Related

Configuration Error : The DNS query name does not exist:_mongodb._tcp.nonr.mongodb.net

ConfigurationError at /testapi/
The DNS query name does not exist: _mongodb._tcp.none.mongodb.net.
Output with error:
utlis.py
for extracting db list from mongo db
This code works fine when run on a different python file, but I'm getting error when I run with a django project.
from urllib.parse import quote_plus
from pymongo import MongoClient
def auth(username, password, cluster_uri):
username = quote_plus(username)
password = quote_plus(password)
conn_str = "mongodb+srv://{}:{}#{}.mongodb.net/?retryWrites=true&w=majority".format(
username,
password,
cluster_uri
)
return MongoClient(conn_str)
def getDatabaseList(username, password, cluster_address):
client = auth(username, password, cluster_address)
dbs = client.list_database_names() # returns a list of databases
return dbs
views.py
from rest_framework import status
from rest_framework.decorators import permission_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny, IsAuthenticated
from .utils import getDatabaseList
u/permission_classes([AllowAny])
class TestViewSet(APIView):
def post(self, request):
username = request.data.get('username')
password = request.data.get('password')
cluster_address = request.data.get('cluster_address')
dblist = getDatabaseList(username, password, cluster_address)
return Response({'dblist': dblist}, status=status.HTTP_200_OK)
I got the solution. Instead of using request.get.data('name')
using request.POST['name'] worked flawlessly

Flask-Admin returns "ValueError: Invalid format string" on clicking create for any model

I have an existing Flask project which uses SQLAlchemy and I wanted to interate an Admin dashboard. Everything worked fine, I managed to enable authentication by using the ModelView Class however if I try to edit or if I try to create a new object of any database model then Flask-Admin throws out the following error:
ValueError: Invalid format string
Here's my Flask-Admin Code:
from flask_admin import Admin
from flask_login import current_user
from flask import redirect, url_for, request
from app import app, db, login
from flask_admin.contrib.sqla import ModelView
from app.auth.models import User
from app.forum.models import thread, post
from app.course.models import Courses
from flask_admin.model import typefmt
from datetime import date
app.config['FLASK_ADMIN_SWATCH'] = 'cerulean'
def date_format(view, value):
return value.strftime('%d.%m.%Y')
MY_DEFAULT_FORMATTERS = dict(typefmt.BASE_FORMATTERS)
MY_DEFAULT_FORMATTERS.update({
type(None): typefmt.null_formatter,
date: date_format
})
class adminmodelview(ModelView):
column_type_formatters = MY_DEFAULT_FORMATTERS
def is_accessible(self):
return (current_user.is_authenticated and current_user.is_admin)
def inaccessible_callback(self, name, **kwargs):
return redirect(url_for('home.index'))
admin = Admin(app, name='celis', template_mode='bootstrap3')
admin.add_view(adminmodelview(User, db.session))
admin.add_view(adminmodelview(post, db.session))
admin.add_view(adminmodelview(thread, db.session))
admin.add_view(adminmodelview(Courses, db.session))
Here's the User Model:
class User(UserMixin,db.Model):
id=db.Column(db.Integer,primary_key=True)
username=db.Column(db.String(64),index=True,unique=True)
email=db.Column(db.String(120),index=True,unique=True)
user_role=db.Column(db.String(20))
is_admin=db.Column(db.Integer, default=0)
Region=db.Column(db.String(20))
password_hash=db.Column(db.String(128))
threads=db.relationship('thread',backref='creator',lazy='dynamic')
posts=db.relationship('post',backref='Author',lazy='dynamic')
last_seen=db.Column(db.DateTime,default=datetime.utcnow)
twitter=db.Column(db.String(120),default="N/A")
facebook=db.Column(db.String(120),default="N/A")
instagram=db.Column(db.String(120),default="N/A")
birthdate=db.Column(db.String(120),default="N/A")
Interests=db.Column(db.String(200),default="N/A")
provides_course=db.relationship('Courses',backref="Teacher",lazy='dynamic')
def __repr__(self):
return '<Role:{} Name:{} Id:{}>'.format(self.user_role,self.username,self.id)
def set_password(self,password):
self.password_hash=generate_password_hash(password)
def check_password(self,password):
return check_password_hash(self.password_hash,password)
def get_reset_token(self, expires_sec=1800):
s = Serializer(app.config['SECRET_KEY'], expires_sec)
return s.dumps({'id': self.id}).decode('utf-8')
On searching I found out it could be an issue due to the DateTime presentation, but could not figure out the solution.
bro I had a similar issue to yours, where the exception stemmed from the "date_posted" field in my "Threads" table as by default flask admin reads all data object as a String object so you have to override it as follows in your adminmodelview for example:
form_overrides=dict(date_posted=DateTimeField)

Django Update Middleware to replace decorator

I have the following Decorator which works fine when applied to different views with: #otp_required(login_url='login') on my site:
Decorator
from django.contrib.auth.decorators import user_passes_test
from django_otp import user_has_device
from django_otp.conf import settings
def otp_required(view=None, redirect_field_name='next', login_url=None, if_configured=False):
"""
Similar to :func:`~django.contrib.auth.decorators.login_required`, but
requires the user to be :term:`verified`. By default, this redirects users
to :setting:`OTP_LOGIN_URL`.
:param if_configured: If ``True``, an authenticated user with no confirmed
OTP devices will be allowed. Default is ``False``.
:type if_configured: bool
"""
if login_url is None:
login_url = settings.OTP_LOGIN_URL
def test(user):
return user.is_verified() or (if_configured and user.is_authenticated and not user_has_device(user))
decorator = user_passes_test(test, login_url=login_url, redirect_field_name=redirect_field_name)
return decorator if (view is None) else decorator(view)
However, I’d like to convert this into a Middleware as I want to avoid having to apply a decorator to every view on my site, but not managed to get working.
I tried to amend the following Middleware which I currently have in place which is just for authorised users and has been working but as per above decorator I want this Middleware extended to also have OTP required as well:
Middleware
from django.utils.deprecation import MiddlewareMixin
from django.urls import resolve, reverse
from django.http import HttpResponseRedirect
from wfi_workflow import settings
from django_otp import user_has_device
from django_otp.decorators import otp_required
from django_otp.middleware import is_verified
class LoginRequiredMiddleware(MiddlewareMixin):
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings by setting a tuple of routes to ignore
"""
##otp_required(login_url='login')
def process_request(self, request):
assert hasattr(request, 'user'), """
The Login Required middleware needs to be after AuthenticationMiddleware.
Also make sure to include the template context_processor:
'django.contrib.account.context_processors.account'."""
if not request.user.is_verified() and not request.path.startswith('/admin/') and not request.path.startswith('/account/' ):
current_route_name = resolve(request.path_info).url_name
if not current_route_name in settings.AUTH_EXEMPT_ROUTES:
return HttpResponseRedirect(reverse(settings.LOGIN_URL))
Help is much appreciated.
The fact that you return a HttpResponseRedirect will not work: Django's MiddlewareMixin will simply call the function to (optionally) alter the request, but it will never take the return into account.
What you can do is define middleware in a decorator-like structure, and return the HttpResponseRedirect in case the user should be authenticated with:
from django.urls import resolve, reverse
from django.http import HttpResponseRedirect
from wfi_workflow import settings
def OTPRequiredMiddleware(get_response):
"""
Middleware that requires a user to be authenticated to view any page other
than LOGIN_URL. Exemptions to this requirement can optionally be specified
in settings by setting a tuple of routes to ignore
"""
def middleware(request):
from django_otp import user_has_device
if not user.is_verified() and not (if_configured and user.is_authenticated and not user_has_device(user)):
return HttpResponseRedirect(settings.OTP_LOGIN_URL)
return get_response(request)

Django Create a user using only Email and set as inactive

In my app I have 3 kind of users with different permissions. HR, Employees and candidate.
I would like to be able to create a User employee providing only its email ans set it as inactive And when the employee sign in into the app he setup a his first name, last name and a password and become Active on the app
I am starting in django and have really no idea how to do it;
I started the authentication process using the documentation and I get to :
views.py :
from django.shortcuts import render
from .forms import HRForm, CandidateForm, EmployeeForm
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.backends import ModelBackend
from .models import MyUser
def registerEmployee(request):
registered = False
if request.method == "POST":
Employee_form = EmployeeForm(data=request.POST)
if Employee_form.is_valid():
user = Employee_form.save()
user.set_password(user.password)
user.is_employee = True
user.save()
registered = True
else:
print("Error!")
else:
Employee_form = EmployeeForm()
return render(request,'Employee_registration_form.html',
{'Employee_form':Employee_form,
'registered':registered})
Could you please help me or give me direction to dive in ?
Thx you ;)
For activating/deactivating a user you could use:
user.is_active = False/True
For creating the user I recommend the following article:
https://medium.com/#ramykhuffash/django-authentication-with-just-an-email-and-password-no-username-required-33e47976b517

Django. Сheck activation code

UPDATE!
The activation code is stored in the database, but I can not call it as a function of activation
Gives an error message:
TypeError at /account/activation/18d2ecbee1fd15440bbcfdf942c071a2f5b8d0ff/
activation() got an unexpected keyword argument 'activation_key'
forms.py
from django import forms
from django.contrib.auth.models import User
class EmailForm(forms.Form):
email = forms.EmailField(widget=forms.EmailInput(
attrs={'class': 'form-control input-lg',
'placeholder': 'Ваш E-mail'}))
views.py
import datetime
import hashlib
import random
from django.conf import settings
from django.contrib.auth import authenticate, logout, login
from django.contrib.auth.decorators import login_required
from django.core.mail import send_mail
from django.http import HttpResponseRedirect, HttpResponse
from django.http import Http404
from django.shortcuts import render
from forms import *
from models import *
def register(request):
if request.method == "POST":
form = EmailForm(request.POST)
if form.is_valid():
form_email = form.cleaned_data['email']
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
activation_key = hashlib.sha1(salt+form_email).hexdigest()
key_expires = datetime.datetime.today() + datetime.timedelta(2)
subject = 'Activation your e-mail'
from_email = settings.EMAIL_HOST_USER
to_email = [form_email]
message_email = "Hi, i'm link activate e-mail! \
http://127.0.0.1:8000/account/activation/%s" % activation_key
send_mail(subject,
message_email,
from_email,
to_email,
fail_silently=True)
code = ActivationEmail.objects.create(activation_key=activation_key)
code.save()
return render(request, 'registration/activate.html', locals())
else:
form = EmailForm()
return render(request, 'registration/register.html', locals())
def activation(request, code):
try:
active = ActivationEmail.objects.get(activation_key=code)
except ActivationEmail.DoesNotExist:
active = None
active.validated = True
if not active:
raise Http404
print "USER WAS HERE?!"
return HttpResponseRedirect('/account/wizard/')
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns('',
url(r'^register/', views.register, name='registration'),
url(r'^activation/(?P<activation_key>\w+)/', views.activation, name='activation'),
url(r'^login/$', views.user_login, name='login'),
url(r'^logout/$', views.user_logout, name='logout'),
Just can not figure out how to do next; (
You will need to
1- You will need to create a new table to store the activation keys, such that you can create a new entry before sending the email
2.- On the user clicking the activation link, that link should be sufficient for you to find the record you created before sending the email
3.- If everything matches, then set a user.is_active type thing on your user model.
But all that said, you are reinventing the wheel here. There are several top notch packages you can use with this and more. I would recommend django-allauth with also give you social login support (e.g. facebook). If you just want the activation portion, there is an older package called django-registration. There are a few others if you search around, but the point is you don't need to implement this (and you probably don't want to mess around with registration if you are not an expert)