Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
48 changes: 43 additions & 5 deletions .github/workflows/development_pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,46 @@
name: hello-world
on: push
name: development
on:
pull_request:
branches: develop

push:
branches:
- develop
jobs:
my-job:
build-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13.3
env:
POSTGRES_USER: db_user
POSTGRES_PASSWORD: db_password
POSTGRES_DB: db_test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: my-step
run: echo "Hello World with Github Actions"
- name: Checkout code
uses: actions/checkout@v2

- name: Cache Python dependencies
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9

- name: Install Python dependencies
run: python -m pip install -r requirements.txt

- name: Unit Tests and Integration Tests
env:
DATABASE_TEST_URL: postgresql://db_user:db_password@localhost/db_test
run: python -m flask tests

6 changes: 4 additions & 2 deletions .github/workflows/production_pipeline.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
name: hello-world
on: push
name: production
on:
pull_request:
branches: main
jobs:
my-job:
runs-on: ubuntu-latest
Expand Down
43 changes: 38 additions & 5 deletions .github/workflows/staging_pipeline.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,41 @@
name: hello-world
on: push
name: staging
on:
pull_request:
branches: staging
jobs:
my-job:
build-test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13.3
env:
POSTGRES_USER: db_user
POSTGRES_PASSWORD: db_password
POSTGRES_DB: db_test
ports:
- 5432:5432
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: my-step
run: echo "Hello World with Github Actions"
- name: Checkout code
uses: actions/checkout@v2

- name: Cache Python dependencies
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9

- name: Install Python dependencies
run: python -m pip install -r requirements.txt

- name: Unit Tests and Integration Tests
env:
DATABASE_TEST_URL: postgresql://db_user:db_password@localhost/db_test
run: python -m flask tests
6 changes: 4 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
from flask import Flask
from app.extention import migrate, jwt, cors
from app.extention import migrate, cors
from app.utils.auth import jwt
from app.utils.principal import principal
from app.utils.logging import configure_logging
from app.db import db
from app.blueprint import register_routing
Expand All @@ -15,6 +17,7 @@ def create_app(settings_module):
migrate.init_app(app, db)
jwt.init_app(app)
cors.init_app(app, supports_credentials='true' ,resources={r"*": { "origins": "*" }})
principal.init_app(app)
manage.init_app(app)

# Logging configuration
Expand All @@ -25,6 +28,5 @@ def create_app(settings_module):

return app


settings_module = os.getenv('APP_SETTINGS_MODULE')
app = create_app(settings_module)
9 changes: 9 additions & 0 deletions app/controllers/permission_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,23 @@
from flask_jwt_extended import jwt_required
from app.schemas.user_schema import PermissionSchema, UpdatePermissionRoleSchema

# Define permissions
read_permission = Permission(RoleNeed('read'))
write_permission = Permission(RoleNeed('write'))

blp = Blueprint("Permission", __name__, description="Permission API")

@blp.route("/permission")
class PermissionList(MethodView):
@jwt_required()
@read_permission.require(http_exception=403)
@blp.response(200, PermissionSchema(many=True))
def get(self):
result = permission_service.get_all_permission()
return result

@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(PermissionSchema)
def post(self, qa_history_data):
result = permission_service.post_permission(qa_history_data)
Expand All @@ -24,12 +30,14 @@ def post(self, qa_history_data):
@blp.route("/permission/<int:permission_id>")
class Permission(MethodView):
@jwt_required()
@read_permission.require(http_exception=403)
@blp.response(200, PermissionSchema)
def get(self, permission_id):
result = permission_service.get_permission(permission_id)
return result

@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(PermissionSchema)
def put(self, permission_data, permission_id):
result = permission_service.update_permission(permission_data, permission_id)
Expand All @@ -38,6 +46,7 @@ def put(self, permission_data, permission_id):
@blp.route("/permission-role-update")
class PermissionRole(MethodView):
@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(UpdatePermissionRoleSchema)
def put(self, permission_data):
result = role_permission_service.update_roles_to_permission(permission_data)
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/role_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@
from flask_jwt_extended import jwt_required
from app.schemas.user_schema import RoleSchema, UpdateRolePermissionSchema

# Define permissions
read_permission = Permission(RoleNeed('read'))
write_permission = Permission(RoleNeed('write'))
delete_permission = Permission(RoleNeed('delete'))

blp = Blueprint("Role", __name__, description="Role API")

@blp.route("/role")
class RoleList(MethodView):
@jwt_required()
@read_permission.require(http_exception=403)
@blp.response(200, RoleSchema(many=True))
def get(self):
result = role_service.get_all_role()
return result

@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(UpdateRolePermissionSchema)
def post(self, qa_history_data):
result = role_service.post_role(qa_history_data)
Expand All @@ -24,18 +31,21 @@ def post(self, qa_history_data):
@blp.route("/role/<int:role_id>")
class Role(MethodView):
@jwt_required()
@read_permission.require(http_exception=403)
@blp.response(200, RoleSchema)
def get(self, role_id):
result = role_service.get_role(role_id)
return result

@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(UpdateRolePermissionSchema)
def put(self, role_data, role_id):
result = role_service.update_role(role_data, role_id)
return result

@jwt_required()
@delete_permission.require(http_exception=403)
def delete(self, role_id):
result = role_service.delete_role(role_id)
return result
21 changes: 10 additions & 11 deletions app/controllers/user_controller.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
from app.services import user_service
from flask_jwt_extended import jwt_required, get_jwt, get_jwt_identity, create_access_token
from flask_jwt_extended import jwt_required, get_jwt
from flask.views import MethodView
from flask_smorest import Blueprint, abort
from flask_smorest import Blueprint
from flask_principal import Permission, RoleNeed
from app.schemas.user_schema import *

# Define some permissions
# admin_permission = Permission(RoleNeed('user_management'))
# Define permissions
read_permission = Permission(RoleNeed('read'))
write_permission = Permission(RoleNeed('write'))
delete_permission = Permission(RoleNeed('delete'))

blp = Blueprint("User", __name__, description="User API")

@blp.route("/user")
class UserList(MethodView):
@jwt_required()
# @admin_permission.require(http_exception=403)
@read_permission.require(http_exception=403)
@blp.response(200, UserSchema(many=True))
def get(self):
result = user_service.get_all_user()
Expand All @@ -22,26 +24,23 @@ def get(self):
@blp.route("/user/<int:user_id>")
class User(MethodView):
@jwt_required()
@read_permission.require(http_exception=403)
@blp.response(200, UserSchema)
def get(self, user_id):
result = user_service.get_user(user_id)
return result

@jwt_required()
@write_permission.require(http_exception=403)
@blp.arguments(UserUpdateSchema)
def put(self, user_data, user_id):
result = user_service.update_user(user_data, user_id)
return result

@jwt_required()
def delete(self, user_id):
result = user_service.delete_user(user_id)
return result

@blp.route("/block-user/<int:user_id>")
class BlockUser(MethodView):
@jwt_required()
# @admin_permission.require(http_exception=403)
@delete_permission.require(http_exception=403)
@blp.arguments(UpdateBlockUserSchema)
def put(self, user_data, user_id):
result = user_service.update_block_user(user_data, user_id)
Expand Down
2 changes: 2 additions & 0 deletions app/extention.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from flask_migrate import Migrate
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from flask_principal import Principal

migrate = Migrate()
jwt = JWTManager()
cors = CORS()
principal = Principal()
2 changes: 1 addition & 1 deletion app/models/permission_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ class PermissionModel(db.Model):

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(), unique=True, nullable=False)
route = db.Column(db.String(), unique=True, nullable=False)
description = db.Column(db.String())
roles = db.relationship("RoleModel", back_populates="permissions", secondary="role_permission")

2 changes: 1 addition & 1 deletion app/models/user_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class UserModel(db.Model):
__tablename__ = "user"

id = db.Column(db.Integer, primary_key = True)
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(), nullable=False)
block = db.Column(db.Boolean, default=False, nullable=False)
Expand Down
8 changes: 4 additions & 4 deletions app/services/permission_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ def get_all_permission():

def post_permission(permission_data):
name = permission_data['name']
route = permission_data['route']
description = permission_data['description']

try:
new_row = PermissionModel(name=name, route=route)
new_row = PermissionModel(name=name, description=description)

db.session.add(new_row)
db.session.commit()
Expand All @@ -36,8 +36,8 @@ def update_permission(permission_data, permission_id):
if permission_data['name']:
permission.name = permission_data['name']

if permission_data['route']:
permission.route = permission_data['route']
if permission_data['description']:
permission.description = permission_data['description']

db.session.commit()
except:
Expand Down
5 changes: 5 additions & 0 deletions app/services/user_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ def update_user(user_data, user_id):
return {"message": "Update successfully!"}

def update_block_user(user_data, user_id):
# Only admin can delete user
jwt = get_jwt()
if not jwt.get("is_admin"):
abort(401, message="Admin privilege requierd.")

if user_id == 1:
abort(401, message="Can not block Super Admin!")

Expand Down
Empty file added app/utils/__init__.py
Empty file.
3 changes: 1 addition & 2 deletions app/utils/auth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from app.extention import jwt
from app.models.user_model import UserModel
from app.models import UserModel, BlocklistModel
from flask import jsonify
from models.blocklist_model import BlocklistModel

@jwt.token_verification_loader
def custom_token_verification_callback(jwt_header, jwt_data):
Expand Down
31 changes: 14 additions & 17 deletions app/utils/principal.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
# from app.models.user_model import UserModel
# from flask_principal import Principal, identity_loaded, RoleNeed
# from app import app
from app.models import UserModel
from app.extention import principal
from flask_principal import identity_loaded, RoleNeed

# # Initialize Flask-Principal
# principal = Principal(app)

# # Define a function to load the user's identity
# @identity_loaded.connect_via(app)
# def on_identity_loaded(sender, identity):
# # Get User
# user = UserModel.query.filter_by(id=identity.id).first()
# Define a function to load the user's identity
@identity_loaded.connect
def on_identity_loaded(sender, identity):
# Get User
user = UserModel.query.filter_by(id=identity.id).first()

# # Get all unique permissions
# for role in user.roles:
# # get permission
# for permission in role.permissions:
# # Add the user's roles to the identity object
# identity.provides.add(RoleNeed(permission.route))
# Get all unique permissions
for role in user.roles:
# get permission
for permission in role.permissions:
# Add the user's roles to the identity object
identity.provides.add(RoleNeed(permission.name))
Loading