Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP -User management - users resource #34

Draft
wants to merge 37 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ee7e3ef
Created db models and configured app
DoRTaL94 Apr 10, 2020
1b7aaf8
adding .gitignore
ahinoamta Apr 11, 2020
345daf4
editing the models User, Token and ResponseUser
ahinoamta Apr 11, 2020
1bf76b8
adding db_hanlder
ahinoamta Apr 11, 2020
92482f1
Updating db handler
DoRTaL94 Apr 11, 2020
5bde4d5
Added required packages to setup.sh and forwarded additional port for…
DoRTaL94 Apr 11, 2020
daf8484
added new line
ahinoamta Apr 12, 2020
82e7381
Merge branch 'master' into user-management
ahinoamta Apr 12, 2020
4a1e0ce
added necessary packages to requirements.txt file
ahinoamta Apr 12, 2020
ba95634
CR fixes
ahinoamta Apr 12, 2020
aeac940
Modified user, db_handler and token files
DoRTaL94 Apr 12, 2020
9580175
added abstract base class BaseStorageHandler that DbHandler derives from
ahinoamta Apr 13, 2020
21dad4f
Fixed token query
DoRTaL94 Apr 14, 2020
e605ac5
Modified generic dbhandler
DoRTaL94 Apr 15, 2020
ced0fc6
Added packages versions in requirements file
DoRTaL94 Apr 15, 2020
58e36fb
Merge pull request #2 from DoRTaL94/user-management
RoniRush Apr 16, 2020
6dddc17
add new line
RoniRush Apr 16, 2020
24650eb
Changed flask_init name
DoRTaL94 Apr 16, 2020
fa860bb
Moved to standard way of configuring DB connection string
DoRTaL94 Apr 16, 2020
75f3a5c
Removed unnecessary DBHandler.
DoRTaL94 Apr 16, 2020
c982f0c
Changed app file name
DoRTaL94 Apr 16, 2020
a62e89c
Added config file
DoRTaL94 Apr 16, 2020
f2b3494
Updated setup.sh
DoRTaL94 Apr 16, 2020
2dd0d61
Changed Vagrantfile
DoRTaL94 Apr 16, 2020
156c181
Updated gitignore
DoRTaL94 Apr 20, 2020
81cb5fc
Improved the load of config object
DoRTaL94 Apr 20, 2020
4e995c4
Fixed token model repr function
DoRTaL94 Apr 20, 2020
b9a2458
Set ports global variables
DoRTaL94 Apr 20, 2020
197a78b
Changed Vagrantfile network definition to private
DoRTaL94 Apr 20, 2020
e99de6f
Merge pull request #3 from DoRTaL94/user-management
RoniRush Apr 21, 2020
2175bb6
Merge remote-tracking branch 'upstream/master' into user-management-u…
RoniRush Apr 21, 2020
9dc4d4c
Merge branch 'user-management-user_resource' of https://github.com/Ro…
RoniRush Apr 21, 2020
7bec14b
Merge branch 'master' of https://github.com/knowabli/edison into user…
DoRTaL94 Apr 21, 2020
9cbfdee
Restructured project layout
DoRTaL94 Apr 21, 2020
cefcbc9
Merged both flask servers into one
DoRTaL94 Apr 21, 2020
4dfdd63
Merge pull request #4 from DoRTaL94/user-management
RoniRush Apr 21, 2020
83a9ae7
add users resource - get all users
RoniRush Apr 21, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

#Build result

*.log
_pycache_/
/.vagrant/*
*/.idea/*
*.box
*.pyc
_pycache_/

6 changes: 1 addition & 5 deletions Vagrantfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
FLASK_PORT=5000
POSTGRESQL_PORT=5432

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.provision :shell, path: "setup.sh"
config.vm.network :forwarded_port, guest: FLASK_PORT, host: FLASK_PORT
config.vm.network :forwarded_port, guest: POSTGRESQL_PORT, host: POSTGRESQL_PORT
config.vm.network "private_network", type: "dhcp"
config.vm.provider "virtualbox" do |v|
v.gui = false
v.name = "Edison_test"
Expand Down
12 changes: 12 additions & 0 deletions edison/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import os

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from edison.config import get_config_object


# Put app and db here so the entire app could import them.
app = Flask(__name__)
app.config.from_object(get_config_object(app.config["ENV"]))
basedir = os.path.abspath(os.path.dirname(__file__))
db = SQLAlchemy(app)
31 changes: 31 additions & 0 deletions edison/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import edison
from flask import render_template
from flask_restful import Api
from flask_jwt_extended import JWTManager
from edison.resources import *
import edison.models as models


# API description in swagger - https://app.swaggerhub.com/apis/DoRTaL94/UserManagment/1.0.0

app = edison.app
# Creates all tables in app. Table's name defined with __tablename__ variable.
edison.db.create_all()
api = Api(app)
# Creation of Json-Web-Token manager.
# In order to reach secured endpoints client should add an authorization header with the value Bearer <token>.
jwt = JWTManager(app)


@jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
jti = decrypted_token['jti']
filters = {'jti': jti}
return models.Token.query.filter_by(**filters).first() is not None


@app.route("/")
def index():
return render_template('index.html')

api.add_resource(Users, '/api/users')
39 changes: 39 additions & 0 deletions edison/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import secrets
import importlib, inspect
import sys, inspect

config_dict = {}

# If config_dict is empty this function builds it dynamically
# and returns the appropriate config object path.
def get_config_object(env_keyword: str):
if(len(config_dict) == 0):
# Iterating through all config.py members
for name, obj in inspect.getmembers(sys.modules[__name__]):
# We're interested only with the derived classes of the Config class
if inspect.isclass(obj) and name != "Config":
config_dict[obj.ENV_KEYWORD] = ".".join([obj.__module__, name])

return config_dict[env_keyword]

class Config:
ENV_KEYWORD = ""
DEBUG = False
# Turn off the Flask-SQLAlchemy event system
SQLALCHEMY_TRACK_MODIFICATIONS = False
# Enables response message for unauthenticated requests
PROPAGATE_EXCEPTIONS = True
# This tells the JWTManager to use jwt.token_in_blacklist_loader callback
JWT_BLACKLIST_ENABLED = True
# JWTManager uses this secret key for creating tokens
JWT_SECRET_KEY = secrets.token_hex(24)
# We're going to check if both access_token and refresh_token are black listed
JWT_BLACKLIST_TOKEN_CHECKS = ['access', 'refresh']
SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:[email protected]/edison'

class ProductionConfig(Config):
ENV_KEYWORD = "production"

class DevelopmentConfig(Config):
ENV_KEYWORD = "development"
DEBUG = True
2 changes: 2 additions & 0 deletions edison/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from .token import Token
from .user import User
12 changes: 12 additions & 0 deletions edison/models/token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from edison import db


class Token(db.Model):
__tablename__ = 'token_blacklist'

id = db.Column(db.Integer, primary_key=True)
jti = db.Column(db.String(150), nullable=False, unique=True)
creation_timestamp = db.Column(db.TIMESTAMP(timezone=False), nullable=False)

def __repr__(self):
return f"<Token: jti: {self.jti}, creation time: {self.creation_timestamp}>"
25 changes: 25 additions & 0 deletions edison/models/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from edison import db


class User(db.Model):
__tablename__ = 'users'
__table_args__ = {'extend_existing': True}

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), nullable=False, unique=True)
password = db.Column(db.String(150), nullable=False)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
email = db.Column(db.String(150), nullable=False)

def to_json(self):
return {
"username": self.username,
"first_name": self.first_name,
"last_name": self.last_name,
"email": self.email
}

def __repr__(self):
return f"<User: id = {self.id}, first_name = {self.first_name}, " \
f"last_name = {self.last_name}, username = {self.username}, email = {self.email}>"
4 changes: 4 additions & 0 deletions edison/resources/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from .user import User
from .users import Users
from .login import Login
from .signup import SignUp
17 changes: 17 additions & 0 deletions edison/resources/users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from flask_restful import Resource
from flask_jwt_extended import jwt_required
import edison.models as models


class Users(Resource):

@jwt_required
def get(self):
status = 200
response = list(
map(
lambda user: user.to_json(), models.User.query.all()
)
)

return response, status
File renamed without changes
File renamed without changes.
10 changes: 0 additions & 10 deletions flask_init.py

This file was deleted.

5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
Flask==1.1.1
flask-restful==0.3.8
flask-jwt-extended==3.24.1
passlib==1.7.2
flask-sqlalchemy==2.4.1
psycopg2-binary==2.8.5
17 changes: 14 additions & 3 deletions setup.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/bash

FLASK_PORT=5000

echo "updating apt before installation"
sudo apt-get update

Expand All @@ -15,6 +17,15 @@ sudo apt-get install -y postgresql postgresql-contrib
echo "install requirements"
pip3 install -r /vagrant/requirements.txt

echo "running flask_init.py"
export FLASK_APP=/vagrant/flask_init.py
python3 -m flask run --host=0.0.0.0 >> /vagrant/log.log 2>&1 &
echo "configuring database"
sudo su postgres <<POSTGRESQL_COMMANDS
psql
CREATE DATABASE edison;
ALTER ROLE postgres WITH PASSWORD 'edison';
POSTGRESQL_COMMANDS

export FLASK_ENV=development

echo "running app.py"
export FLASK_APP=/vagrant/edison/app.py
flask run -h 0.0.0.0 -p $FLASK_PORT >> /vagrant/edison/app.log 2>&1 &
11 changes: 11 additions & 0 deletions tests/init_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import unittest
import requests

class Tester(unittest.TestCase):
def test_home(self):
response = requests.get("http://127.0.0.1:5000")
self.assertEqual(response.status_code, 200)


if __name__ == '__main__':
unittest.main()