Initial commit

This commit is contained in:
Josako
2024-04-22 21:23:00 +02:00
parent 48cc80db17
commit fd25c39395
24 changed files with 748 additions and 8 deletions

43
eveai_app/__init__.py Normal file
View File

@@ -0,0 +1,43 @@
import os
from flask import Flask
from .extensions import db, migrate, bcrypt, bootstrap, jwt
from .models.user import User, Tenant
def create_app(config_file=None):
app = Flask(__name__)
if config_file is None:
app.config.from_object('config.DevConfig')
else:
app.config.from_object(config_file)
try:
os.makedirs(app.instance_path)
except OSError:
pass
register_extensions(app)
register_blueprints(app)
print(app.config.get('SQLALCHEMY_DATABASE_URI'))
return app
def register_extensions(app):
db.init_app(app)
migrate.init_app(app, db)
bcrypt.init_app(app)
bootstrap.init_app(app)
jwt.init_app(app)
def register_blueprints(app):
from .views.user_views import user_bp
app.register_blueprint(user_bp)
def register_api(app):
pass
# from . import api
# app.register_blueprint(api.bp, url_prefix='/api')

View File

@@ -0,0 +1,4 @@
# from flask import Blueprint, request
#
# public_api_bp = Blueprint("public", __name__, url_prefix="/api/v1")
# tenant_api_bp = Blueprint("tenant", __name__, url_prefix="/api/v1/tenant")

7
eveai_app/api/auth.py Normal file
View File

@@ -0,0 +1,7 @@
from flask import request
from flask.views import MethodView
class RegisterAPI(MethodView):
def post(self):
username = request.json['username']

12
eveai_app/extensions.py Normal file
View File

@@ -0,0 +1,12 @@
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase
from flask_migrate import Migrate
from flask_bcrypt import Bcrypt
from flask_bootstrap import Bootstrap
from flask_jwt_extended import JWTManager
db = SQLAlchemy()
migrate = Migrate()
bcrypt = Bcrypt()
bootstrap = Bootstrap()
jwt = JWTManager()

View File

@@ -0,0 +1,3 @@

View File

View File

61
eveai_app/models/user.py Normal file
View File

@@ -0,0 +1,61 @@
from ..extensions import db
class Tenant(db.Model):
"""Tenant model"""
__bind_key__ = 'public'
__table_args__ = {'schema': 'public'}
# Versioning Information
created_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now())
updated_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now(), onupdate=db.func.now())
# company Information
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
website = db.Column(db.String(255), nullable=True)
# Licensing Information
license_start_date = db.Column(db.Date, nullable=True)
license_end_date = db.Column(db.Date, nullable=True)
allowed_monthly_interactions = db.Column(db.Integer, nullable=True)
# Relations
users = db.relationship('User', backref='tenant')
def __repr__(self):
return '<Tenant %r>' % self.name
class User(db.Model):
"""User model"""
__bind_key__ = 'public'
__table_args__ = {'schema': 'public'}
# Versioning Information
created_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now())
updated_at = db.Column(db.DateTime, nullable=False, server_default=db.func.now(), onupdate=db.func.now())
# User Information
id = db.Column(db.Integer, primary_key=True)
user_name = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
first_name = db.Column(db.String(80), nullable=False)
last_name = db.Column(db.String(80), nullable=False)
is_active = db.Column(db.Boolean, default=True)
is_tester = db.Column(db.Boolean, default=False)
is_admin = db.Column(db.Boolean, default=False)
valid_to = db.Column(db.Date, nullable=True)
# Login Information
last_login = db.Column(db.DateTime, nullable=True)
authenticated = db.Column(db.Boolean, default=False)
# Relations
tenant_id = db.Column(db.Integer, db.ForeignKey('public.tenant.id'), nullable=False)
def __repr__(self):
return '<User %r>' % self.name()

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div><a href="/register">Register</a></div>
<div><a href="/login">Login</a></div>
<hr>
{% block content %}{% endblock %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

View File

@@ -0,0 +1,29 @@
{% extends 'base.html' %}
{% block title %}Tenant Details{% endblock %}
{% block content %}
<form action="" method="post" novalidate>
<p>
{{ form.name.label }}<br>
{{ form.name(size=80) }}
</p>
<p>
{{ form.website.label }}<br>
{{ form.website(size=80) }}
</p>
<p>
{{ form.license_start_date.label }}<br>
{{ form.license_start_date(size=20) }}
</p>
<p>
{{ form.license_end_date.label }}<br>
{{ form.license_end_date(size=20) }}
</p>
<p>
{{ form.allowed_monthly_interactions.label }}<br>
{{ form.allowed_monthly_interactions(size=20) }}
</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}

View File

@@ -0,0 +1,6 @@
import eveai_app.views.user_views
# document_bp = Blueprint('document_bp', __name__, url_prefix='document')
# interaction_bp = Blueprint('interaction_bp', __name__, url_prefix='interaction')

View File

@@ -0,0 +1,26 @@
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, EmailField, IntegerField, DateField
from wtforms.validators import DataRequired, Length, Email, NumberRange
class TenantForm(FlaskForm):
name = StringField('Name', validators=[DataRequired(), Length(max=80)])
website = StringField('Website', validators=[DataRequired(), Length(max=255)])
license_start_date = DateField('License Start Date', id='datepicker')
license_end_date = DateField('License End Date', id='datepicker')
allowed_monthly_interactions = IntegerField('Allowed Monthly Interactions', validators=[NumberRange(min=0)])
submit = SubmitField('Submit')
class UserForm(FlaskForm):
user_name = StringField('Name', validators=[DataRequired(), Length(max=80)])
email = EmailField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired(), Length(min=8)])
first_name = StringField('First Name', validators=[DataRequired(), Length(max=80)])
last_name = StringField('Last Name', validators=[DataRequired(), Length(max=80)])
is_active = BooleanField('Is Active')
is_tester = BooleanField('Is Tester')
is_admin = BooleanField('Is Administrator')
valid_to: DateField('Valid To', id='datepicker')
tenant = IntegerField('Tenant ID', validators=[NumberRange(min=0)])
submit = SubmitField('Submit')

View File

@@ -0,0 +1,106 @@
# from . import user_bp
from datetime import datetime as dt, timezone as tz
from flask import request, redirect, url_for, flash, render_template, Blueprint
from ..models.user import User, Tenant
from ..extensions import db
from .user_forms import TenantForm, UserForm
user_bp = Blueprint('user_bp', __name__, url_prefix='/user')
@user_bp.route('/tenant', methods=['GET', 'POST'])
def tenant():
if request.method == 'POST':
# Handle the required attributes
name = request.form.get('name')
website = request.form.get('website')
error = None
if not name:
error = 'Tenant name is required.'
elif not website:
error = 'Tenant website is required.'
# Create new tenant if there is no error
if error is None:
new_tenant = Tenant(name=name, website=website)
# Handle optional attributes
lic_start = request.form.get('license_start_date')
lic_end = request.form.get('license_end_date')
monthly = request.form.get('allowed_monthly_interactions')
if lic_start != '':
new_tenant.license_start_date = dt.strptime(lic_start, '%d-%m-%Y')
if lic_end != '':
new_tenant.license_end_date = dt.strptime(lic_end, '%d-%m-%Y')
if monthly != '':
new_tenant.allowed_monthly_interactions = int(monthly)
# Handle Timestamps
timestamp = dt.now(tz.utc)
new_tenant.created_at = timestamp
new_tenant.updated_at = timestamp
# Add the new tenant to the database and commit the changes
try:
db.session.add(new_tenant)
db.session.commit()
except Exception as e:
error = e.args
flash(error) if error else flash('Tenant added successfully.')
form = TenantForm()
return render_template('user/tenant.html', form=form)
@user_bp.route('/user', methods=['GET', 'POST'])
def user():
if request.method == 'POST':
# Handle the required attributes
username = request.form.get('username')
email = request.form.get('email')
password = request.form.get('password')
first_name = request.form.get('first_name')
last_name = request.form.get('last_name')
error = None
if not username:
error = 'Username is required.'
elif not email:
error = 'Email is required.'
elif not password:
error = 'Password is required.'
elif not first_name:
error = 'First name is required.'
elif not last_name:
error = 'Last name is required.'
if error is None:
new_user = User(username=username, email=email, password=password, first_name=first_name, last_name=last_name)
# Handle optional attributes
new_user.is_active = request.form.get('is_active')
new_user.is_tester = request.form.get('is_tester')
new_user.is_admin = request.form.get('is_admin')
new_user.valid_to = request.form.get('valid_to')
# Handle Timestamps
timestamp = dt.now(tz.utc)
new_user.created_at = timestamp
new_user.updated_at = timestamp
# Handle the relations
new_user.tenant_id = request.form.get('tenant_id')
try:
db.session.add(new_user)
db.session.commit()
except Exception as e:
error = e.args
flash(error) if error else flash('User added successfully.')
form = UserForm()
return render_template('user/user.html', form=form)