Flask Application - Notification System with AWS RDS - amazon-web-services

I am building an application for admins and users in Flask to request/approve requests.
When a user raises a request, the next time the admin logs into the system. I would like the notification bell in my Flask app to reflect the number of new requests.
I understand the HTML, CSS, JS changes and have been using Python for 2+ years.
I just want someone to point me in the right direction of how this can be done and what library.
My database is on AWS using Relational Database Service (RDS). I have built the login system, and users can raise requests which adds data to the database. I am just stuck now on how to let the Admin know when logged in.
Your help would be greatly appreciated! I could not see any questions similar to this
I am using MYSQLClient, and I have added my code below of how I display all requests in the terminal, I have other code to display this in Flask App. I would like to just know about newly added requests in the notification dropdown that appears when bell selected.
hostname = 'localhost'
username = 'username'
password = 'password'
database = 'dbname'
def doQuery( conn ) :
cur = conn.cursor()
cur.execute( "SELECT fname, lname FROM employee" )
for firstname, lastname in cur.fetchall() :
print( firstname, lastname )

Related

How to map users to flask session file in server?

I still use the flask session manager for users. My config is like this:
app.config['SECRET_KEY'] = "mySecretKey"
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
app.config['SESSION_USE_SIGNER'] = True
Whenever a user logs in a flask session file is created in the folder app\flask_session. It will be random alphanumeric file name, like 0609ece61011830ef9b6547217b9abd6.
the session file contains the email of the user. What I want to do is to delete a flask session file when a user resets their password, for security reasons. Like the user might have logged in to 5 devices and as the sessions don't expire the user gets to use the account on all 5 devices. But when the user changes the password, I need to delete all these 5 sessions which match the email id so that the user gets logged out on all the devices.
I am ready to loop through each session file. How can I achieve this?
you can use pickle package for that. Here is an example how to parse one of the session files:
import pickle
with open("sessions_dir/701dc705b498a6ee20475e5fcbcbdf99", "rb") as e:
time = pickle.load(e)
data = pickle.load(e)
print(time)
print(data)
You will need to get the email id from the data and act accordingly.

How can i send a webook to my django app and only execute it on logged in user

Hi i am new to coding and only been learning python and django for about a week. so sorry if this does not make sense.
i am trying to send a webhook(this is just a test then ill add json)
so that when i send to http://127.0.0.1:8000/webhook
i am using postmen desktop so i receive the webhooks.
it will execute my session code but the problem i have that in my app i have
already set up users db and when i sent the webhook it return none since no one seems to be logged in. i know i will have to add a code something like a token to specify each user but only want to test with one user first.
i get the error None or when i remove user authenticated then it says i can't send to anonymous user. is there a way i can send it to lets say a specific user or ID or let's say a token i save with the user.
#csrf_exempt
def webhook(request):
#get current users keys
if request.user.is_authenticated:
user = request.user
database = Bybitapidatas.objects.all().filter(user=user)
for apikey in database:
apikey = apikey.apikey
for apisecret in database:
apisecret = apisecret.apisecret
session = HTTP(endpoint='https://api-testnet.bybit.com/', api_key=apikey, api_secret=apisecret,spot=True)
print(session.place_active_order(
symbol="BTCUSDT",
side="Buy",
type="MARKET",
qty="20",
timeInForce="GTC"
))

Tornado with Django authentication

Here's my idea:
have a Django Website that receives / send JSON information so that I can create a JavaScript client for a Webbrowser, or a Unity / UE client
I want a new functionality only for Unity / UE client: realtime chat.
I'd like to use a tornado server on a specific port, let's say 8666.
Here's what I've done so far:
authenticate on the Django web site
make everything work on the Django web site
Now I'd like the client to connect to the port 8666 (pure TCP) and to send something (maybe his session cookie or something else) so that I can see on the tornado web server whether the client is authenticated, and look in the database to find out which other mates are connected too on the tornado webserver, so that when this client writes something, I can dispatch his message to all other "concerned" connected clients.
I didn't find any documentation about that. Do you know how to handle this? Any example, or if I'm not on the right track what should I do then?
If your Tornado process runs on the same domain as your Django application, the session cookie will be sent by the browser upon websocket handshake, and accessible through the WebSocketHandler.get_cookie() method.
Here is an example, assuming a global variable CLIENTS keeping track of connected authentified clients:
def open(self):
"""Authenticate client based on session cookie, add broadcast notification"""
session_id = self.get_cookie('sessionid')
if not session_id:
self.close()
self.authenticate_user(session_id)
if self.user is None:
self.close()
self.CLIENTS.append(self)
self.notify_all_clients()
def authenticate_user(self, session_id):
"""Retrieve User instance associated to the session key."""
session = SessionStore(session_key=session_id)
user_id = session.get('_auth_user_id')
if user_id is None:
return
try:
user = User.objects.get(pk=user_id)
except User.DoesNotExist:
self.close()
else:
self.user = user
Hope this helps!
Edit:
Note that to be able to use the Django ORM, you must set the DJANGO_SETTINGS_MODULE environment variable to your app's settings module path (e.g. 'myapp.settings', making sure it can be found through sys.path) and then call setup() as explained in the Django docs.

flask_dance: Cannot get OAuth token without an associated user

I want to migrate flask_dance with my application to make the user authorize using google and another social networks.
I am getting this error:
Cannot get OAuth token without an associated user
Before i do the connection between the blueprint and sqlalchemy backend, the application worked just fine, if i removed the google_blueprint.backend line the error disappear.
Here is my __init__.py:
import os
from flask import Flask, redirect, url_for, current_app
from flask_login import current_user
from develop.models import (
db,
User,
OAuth
)
from flask_dance.contrib.google import make_google_blueprint
from flask_dance.consumer.backend.sqla import SQLAlchemyBackend
from flask_dance.consumer import oauth_authorized
from sqlalchemy.orm.exc import NoResultFound
def create_app(config_object):
app = Flask(__name__)
app.config.from_object(config_object)
db.init_app(app)
login_manager.init_app(app)
google_blueprint = make_google_blueprint(
client_id=app.config['GOOGLE_CLIENT_ID'],
client_secret=app.config['GOOGLE_CLIENT_SECRET'],
scope=["profile", "email"]
)
app.register_blueprint(google_blueprint, url_prefix='/login')
#oauth_authorized.connect_via(google_blueprint)
def google_logged_in(blueprint, token):
resp = blueprint.session.get("/oauth2/v2/userinfo")
if resp.ok:
account_info_json = resp.json()
email = account_info_json['email']
query = User.query.filter_by(email=email)
try:
user = query.one()
except NoResultFound:
user = User()
user.image = account_info_json['picture']
user.fullname = account_info_json['name']
user.username = account_info_json['given_name']
user.email = account_info_json['email']
db.session.add(user)
db.session.commit()
login_user(get_user, remember=True)
identity_changed.send(
current_app._get_current_object(),
identity=Identity(get_user.id)
)
#login_manager.user_loader
def load_user(userid):
return User.query.get(userid)
google_blueprint.backend = SQLAlchemyBackend(OAuth, db.session, user=current_user)
return app
Here is also my tables how i organized them in models.py:
class User(db.Model, UserMixin):
id = db.Column(db.Integer(), primary_key=True)
image = db.Column(db.String(), nullable=True)
fullname = db.Column(db.String())
username = db.Column(db.String(), unique=True)
password = db.Column(db.String())
email = db.Column(db.String(), unique=True)
class OAuth(OAuthConsumerMixin, db.Model):
user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
user = db.relationship(User)
Please any help would be appreciated :)
TL;DR: You can disable this exception by setting user_required=False on the SQLAlchemyStorage object. However, the exception is being raised for a reason, and if you simply disable it like this, your database may get into an unexpected state where some OAuth tokens are not linked to users. There's a better way to solve this problem. Read on for details.
I am the author of Flask-Dance. This Cannot get OAuth token without an associated user exception is only present in version 0.13.0 and above of Flask-Dance. (CHANGELOG is here.) The pull request introducing this change has some more context for why the change was made.
There are several different ways to use OAuth. Here are some example use cases, all of which Flask-Dance supports:
I want to build a bot that can connect to one specific service, such as a Twitter bot that tweets to a specific account, or a Slack bot that connects to a specific Slack team. I want this bot to respond to HTTP requests, so it has to run as a website, even though I don't expect people to actually use this website directly.
I want to build a website where users can log in. Users need to create an account on my website using a username and password. After they have created an account, users may decide to link their account to other OAuth providers, like Google or Facebook, to unlock additional functionality.
I want to build a website where users can log in. Users should be able to create their account simply by logging in with GitHub (or any other OAuth provider). Users should not need to create a new password for my website.
Use case 1 is the simplest: do not pass a user or user_id argument to your SQLAlchemyStorage, and it will assume that your application does not use multiple user accounts. This means that your website can only link to one particular account on the remote service: only one Twitter account, only one Slack team, etc.
Use case 2 is also pretty simple: pass a user or user_id argument to your SQLAlchemyStorage. Flask-Dance will save the OAuth token into your database automatically, and link it to the user that is currently logged in.
Use case 3 is more complex, since it involves automatically creating both the OAuth token and the local user account at the same time. Different applications have different requirements for creating user accounts, and there's no way for Flask-Dance to know what those requirements are. As a result, Flask-Dance cannot handle this use case automatically. You must hook into the oauth_authorized signal, create the user account and associate it with the OAuth token manually, and return False to tell Flask-Dance to not attempt to handle the OAuth token automatically.
Before version 0.13.0, it was possible to accidentally create OAuth tokens in the database that were not linked with any users at all. In use case 3, the OAuth token is created before a local user account exists for that user, so Flask-Dance would save the OAuth token to the database without any linked local user account. You could use the oauth_authorized handler to associate the OAuth token with a local user account afterwards, but if your code is buggy and raises an exception, then the OAuth token could remain in your database, forever unlinked to any users.
Starting in version 0.13.0, Flask-Dance detects this problem and raises an exception, instead of saving an OAuth token to your database without an associated local user account. There are two ways to resolve this problem:
Rewrite your code to manually create the user account and associate it with the OAuth token. The documentation contains some example code you can use for this.
Disable this check, and tell Flask-Dance that it's OK to create OAuth tokens without associated users. You can disable this check by setting user_required=False on the SQLAlchemyStorage object.
I believe that option 1 is the better solution by far, but it requires more understanding of what Flask-Dance is actually doing behind the scenes. I've written some documentation that describes how to handle multi-user setups, which discusses this problem as well.

REST login with Django social_auth

I've been asked to provide a "Login with Facebook" functionality to an iOS app I am creating.
The app connects to a REST api created with Piston, the web application is created with Django and uses social_auth. The application also has a Facebook login.
My thought was to create a service 'FBLogin' providing just the Facebook profile UID (separate FB login procedure on iPhone to get the ID). Using the SocialAuth models I can query the DB with uid and provider to fetch the user... but how can i use the authentication mechanism to get this user instance authenticated?
Any ideas on getting this right?
This just doesn't feel good ... getting the user instance authenticated is a pain...
The username password authentication is already implemented ... without a problem.
Btw, don't have django experience ... do have a lot of other development experience so understanding python and django isn't that hard :)
Tx
Y
It doesn't really seem to be documented anywhere, but you can do this in your REST handler:
from social_auth.backends.pipeline.social import associate_user
from social_auth.backends.facebook import FacebookBackend
from social_auth.models import UserSocialAuth
myextra_data = {
'access_token' : 'jfkdlfsdgeyejfghfdsjdfpoweipuo',
'id' : 123456789,
}
usa, created = UserSocialAuth.objects.get_or_create(provider = 'facebook',
uid=123456789)
usa.user = user
usa.extra_data = myextra_data
usa.save()
if created:
associate_user(backend=FacebookBackend, user=user, uid=usa.uid)
These get pretty vendor-specific in terms of how data gets formatted in extra_data so YMMV