Skip to content

Commit

Permalink
Merge pull request #5 from Kalkuli/develop
Browse files Browse the repository at this point in the history
Release 0.1
  • Loading branch information
youssef-md authored Nov 11, 2018
2 parents 7e17c93 + e152157 commit 641566f
Show file tree
Hide file tree
Showing 18 changed files with 770 additions and 61 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ env
.dockerignore
Dockerfile-dev
Dockerfile-prod
htmlcov/
htmlcov/
migrations
3 changes: 2 additions & 1 deletion Dockerfile-dev
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ WORKDIR /app
RUN apk update && \
apk add --virtual build-deps gcc python-dev musl-dev && \
apk add postgresql-dev && \
apk add netcat-openbsd
apk add netcat-openbsd && \
apk add libffi-dev


# Dealing with requirements
Expand Down
2 changes: 2 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web: gunicorn -b 0.0.0.0:$PORT manage:app
release: python manage.py recreatedb
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@

</div>


# Ambientes

### Produção
Para acessar o ambiente de produção utilize o link abaixo:
```https://kalkuli-users.herokuapp.com/```
### Homologação
Para acessar o ambiente de homologação clique no link abaixo:
```https://kalkuli-users-hom.herokuapp.com/```

***

# Configurando o ambiente
Para instruções de como instalar o Docker e o Docker-compose clique [aqui](https://github.com/Kalkuli/2018.2-Kalkuli_Front-End/blob/master/README.md).

Expand All @@ -30,7 +42,7 @@ Abra outro terminal, e execute o comando:


```
docker-compose -f docker-compose-dev.yml run base python manage.py recreate_db
docker-compose -f docker-compose-dev.yml run base python manage.py recreatedb
```

Acesse o servidor local no endereço apresentado abaixo:
Expand Down
1 change: 1 addition & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ services:
- APP_SETTINGS=project.config.DevelopmentConfig
- DATABASE_URL=postgres://postgres:postgres@db:5432/users_dev
- DATABASE_TEST_URL=postgres://postgres:postgres@db:5432/users_test
- SECRET_KEY=my_precious
depends_on:
- db

Expand Down
Empty file modified entrypoint.sh
100644 → 100755
Empty file.
39 changes: 28 additions & 11 deletions manage.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
from flask.cli import FlaskGroup
from project import app, db
from project.api.models import Company, User
import unittest
import coverage


# Config coverage report
COV = coverage.coverage(
branch=True,
include='project/*',
omit=[
'project/tests/*',
'project/config.py',
'project/config.py'
]
)
COV.start()
from flask.cli import FlaskGroup
from project import create_app, db
from project.api.models import Company, User
from project.tests.utils import add_company
import unittest


# Config coverage report


cli = FlaskGroup(app)
cli = FlaskGroup(create_app)


# Registers comand to recreate database
@cli.command()
def recreate_db():
def recreatedb():
db.drop_all()
db.create_all()
db.session.commit()
Expand Down Expand Up @@ -53,7 +54,23 @@ def cov():
return 0
return 1


@cli.command()
def seeduserdb():
company = add_company('Kalkuli', '00.000.000/0000-00', '[email protected]', 'kaliu', '789548546', 'ceilandia', 'df', '40028922')
db.session.add(User(
username='michael',
email='[email protected]',
password='greaterthaneight',
company_id=company.id
))
company_two = add_company('Kalkuli', '00.000.000/0000-00', '[email protected]', 'kaliu', '789548546', 'ceilandia', 'df', '40028922')
db.session.add(User(
username='michaelherman',
email='[email protected]',
password='greaterthaneight',
company_id=company_two.id
))
db.session.commit()

if __name__ == '__main__':
cli()
31 changes: 19 additions & 12 deletions project/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
import os
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_migrate import Migrate

# Instantiate the app
app = Flask(__name__)
# instantiate the extensions
db = SQLAlchemy()
migrate = Migrate()
bcrypt = Bcrypt()

def create_app(script_info=None):
#Instantiate the app
app = Flask(__name__)

# Set Configuration
app_settings = os.getenv('APP_SETTINGS')
app.config.from_object(app_settings)
# Set Configuration
app_settings = os.getenv('APP_SETTINGS')
app.config.from_object(app_settings)

# Instanciate Database
db = SQLAlchemy(app)
# set up extensions
db.init_app(app)
migrate.init_app(app, db)
bcrypt.init_app(app)

from project.api.views import user_blueprint
app.register_blueprint(user_blueprint)

@app.route('/', methods=['GET'])
def ping_pong():
return jsonify({
'data': 'Welcome to Kalkuli Users Service!!'
})
return app
113 changes: 89 additions & 24 deletions project/api/models.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,102 @@
from project import db
from sqlalchemy_utils import PasswordType, EmailType, force_auto_coercion
import datetime
import jwt
from project import create_app
from sqlalchemy_utils import PasswordType, EmailType
from project import bcrypt
from flask import current_app

force_auto_coercion()

class Company(db.Model):
__tablename__ = 'company'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
company_name = db.Column(db.String(128), nullable=False)
cnpj = db.Column(db.Integer, nullable=False)
users = db.relationship('User', backref='company', lazy=True)
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
company_name = db.Column(db.String(128), nullable=False)
cnpj = db.Column(db.String, nullable=True)
user = db.relationship('User', uselist=False, back_populates='company')
company_email = db.Column(db.String(128), nullable=False, unique=True)
fantasy_name = db.Column(db.String(128), nullable=True)
cep = db.Column(db.String(128), nullable=True)
city = db.Column(db.String(128), nullable=True)
state = db.Column(db.String(128), nullable=True)
company_phone = db.Column(db.String(128), nullable=True)

def __init__(self, company_name, cnpj):
self.company_name = company_name
self.cnpj = cnpj
def __init__(self, company_name, cnpj, company_email, fantasy_name, cep, city, state, company_phone):
self.company_name = company_name
self.cnpj = cnpj
self.company_email = company_email
self.fantasy_name = fantasy_name
self.cep = cep
self.city = city
self.state = state
self.company_phone = company_phone

def to_json(self):
return {
'id': self.id,
'company_name': self.company_name,
'cnpj': self.cnpj,
'company_email': self.company_email,
'fantasy_name': self.fantasy_name,
'cep': self.cep,
'city': self.city,
'state': self.state,
'company_phone': self.company_phone
}


class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(128), nullable=False)
email = db.Column(EmailType, nullable=False)
is_admin = db.Column(db.Boolean(), default=False, nullable=False)
company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)
password = db.Column(PasswordType(schemes=[ 'pbkdf2_sha512' ]), unique=False,nullable=False)

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(128), nullable=False)
email = db.Column(EmailType, nullable=False, unique=True)
registered_on = db.Column(db.DateTime, nullable=False)
company_id = db.Column(db.Integer, db.ForeignKey('company.id'), nullable=False)
company = db.relationship('Company', back_populates='user')
active = db.Column(db.Boolean(), default=True, nullable=False)
password = db.Column(db.String(255), unique=False,nullable=False)

def __init__(self, name, email, is_admin, company_id, password):
self.name = name
self.email = email
self.is_admin = is_admin
self.company_id = company_id
self.password = password
def __init__(self, username, email, company_id, password):
self.username = username
self.email = email
self.company_id = company_id
self.password = bcrypt.generate_password_hash(password, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode()
self.registered_on = datetime.datetime.now()

def to_json(self):
return {
'username': self.username,
'email': self.email,
'company_id': self.company_id,
'password': self.password,
'active': self.active
}

def encode_auth_token(self, user_id):
try:
payload = {
'exp': datetime.datetime.utcnow() + datetime.timedelta(
days=current_app.config.get('TOKEN_EXPIRATION_DAYS'),
seconds=current_app.config.get('TOKEN_EXPIRATION_SECONDS')
),
'iat': datetime.datetime.utcnow(),
'sub': user_id
}
return jwt.encode(
payload,
current_app.config.get('SECRET_KEY'),
algorithm='HS256'
)
except Exception as e:
return e




@staticmethod
def decode_auth_token(auth_token):
try:
payload = jwt.decode(
auth_token, current_app.config.get('SECRET_KEY'))
return payload['sub']
except jwt.ExpiredSignatureError:
return 'Signature expired. Please log in again.'
except jwt.InvalidTokenError:
return 'Invalid token. Please log in again.'
29 changes: 29 additions & 0 deletions project/api/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from functools import wraps
from flask import request, jsonify
from project.api.models import User


def authenticate(f):
@wraps(f)
def decorated_function(*args, **kwargs):
response_object = {
'status': 'fail',
'message': 'Provide a valid auth token.'
}
auth_header = request.headers.get('Authorization')

if not auth_header:
return jsonify(response_object), 403
auth_token = auth_header.split(" ")[1]
resp = User.decode_auth_token(auth_token)

if isinstance(resp, str):
response_object['message'] = resp
return jsonify(response_object), 401
user = User.query.filter_by(id=resp).first()

if not user or not user.active:
return jsonify(response_object), 401
return f(resp, *args, **kwargs)

return decorated_function
Loading

0 comments on commit 641566f

Please sign in to comment.