Agregar configuración

This commit is contained in:
Mauricio Baeza 2017-09-21 23:24:18 -05:00
parent 3a4cede680
commit 85c0804ecd
14 changed files with 277 additions and 103 deletions

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python3
import falcon
from . import util
from middleware import get_template
@ -19,11 +17,11 @@ class AppLogin(object):
def on_post(self, req, resp):
session = req.env['beaker.session']
values = req.params
result = self._db.authenticate(values['user'], values['pass'])
resp.body = util.dumps(result)
result = self._db.authenticate(values)
if result['login']:
session.save()
session['user'] = result['user']
req.context['result'] = result
resp.status = falcon.HTTP_200
@ -39,6 +37,17 @@ class AppLogout(object):
raise falcon.HTTPTemporaryRedirect('/')
class AppAdmin(object):
template = 'admin.html'
def __init__(self, db):
self._db = db
@falcon.after(get_template)
def on_get(self, req, resp):
resp.status = falcon.HTTP_200
class AppMain(object):
template = 'main.html'

View File

@ -5,40 +5,36 @@ from beaker.middleware import SessionMiddleware
from middleware import AuthMiddleware, JSONTranslator, static, handle_404
from models.db import StorageEngine
from controllers.main import AppLogin, AppLogout, AppMain, AppPartners
from controllers.helper import AppPostalCode
from settings import DEBUG, WITH_LOGIN
from controllers.main import (
AppLogin, AppLogout, AppAdmin, AppMain,
)
from settings import DEBUG
db = StorageEngine()
pc = AppPostalCode()
login = AppLogin(db)
logout = AppLogout(db)
main = AppMain(db)
partners = AppPartners(db)
#~ partners = AppPartners(db)
api = falcon.API(middleware=[AuthMiddleware(), JSONTranslator()])
api.req_options.auto_parse_form_urlencoded = True
api.add_sink(handle_404, '')
if WITH_LOGIN:
api.add_route('/', login)
api.add_route('/logout', logout)
api.add_route('/main', main)
api.add_route('/partners', partners)
api.add_route('/pc', pc)
api.add_route('/', AppLogin(db))
api.add_route('/logout', AppLogout(db))
api.add_route('/admin', AppAdmin(db))
api.add_route('/main', AppMain(db))
#~ api.add_route('/partners', partners)
if DEBUG:
api.add_sink(static, '/static')
session_opts = {
session_options = {
'session.type': 'file',
'session.cookie_expires': True,
'session.data_dir': '/tmp/cache/data',
'session.lock_dir': '/tmp/cache/lock',
#~ 'session.httponly': True,
#~ 'session.secure': True,
}
app = SessionMiddleware(api, session_opts)
app = SessionMiddleware(api, session_options)

View File

@ -31,12 +31,9 @@ def static(req, res):
class AuthMiddleware(object):
#~ def process_request(self, req, resp):
def process_resource(self, req, resp, resource, params):
paths = ('/main', '/partners', '/cp')
id_session = req.cookies.get('beaker.session.id', '')
if req.path in paths and not id_session:
if not id_session and req.path != '/':
raise falcon.HTTPTemporaryRedirect('/')
@ -46,5 +43,3 @@ class JSONTranslator(object):
if 'result' not in req.context:
return
resp.body = util.dumps(req.context['result'])

View File

@ -6,10 +6,10 @@ from . import main
class StorageEngine(object):
def __init__(self):
main.connect()
main.conectar()
def authenticate(self, username, password):
return main.authenticate(username, password)
def authenticate(self, args):
return main.authenticate(args['usuario'], args['contra'])
def get_partners(self, values):
return main.get_partners(values)

View File

@ -3,12 +3,15 @@
import sqlite3
import click
from peewee import *
from playhouse.fields import PasswordField, ManyToManyField
if __name__ == '__main__':
import os, sys
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent_dir)
from controllers import util
from conf import DATABASE, __version__
from settings import log, PATH_CP
@ -20,50 +23,95 @@ class BaseModel(Model):
database = database
def connect():
def conectar():
global database
database.connect()
log.info('Conectado a la BD...')
return
class Configuration(BaseModel):
key = FixedCharField(max_length=50)
value = FixedCharField(max_length=100)
class Configuracion(BaseModel):
clave = TextField()
valor = TextField()
class Meta:
order_by = ('key',)
order_by = ('clave',)
indexes = (
(('key', 'value'), True),
(('clave', 'valor'), True),
)
class Tags(BaseModel):
tag = FixedCharField(max_length=25, index=True)
tag = TextField(index=True, unique=True)
class Meta:
order_by = ('tag',)
class Users(BaseModel):
username = CharField(max_length=50, unique=True)
first_name = CharField(max_length=50, default='')
last_name = CharField(max_length=50, default='')
email = CharField(max_length=200, default='')
password = CharField(max_length=100)
is_superuser = BooleanField(default=False)
is_admin = BooleanField(default=False)
is_staff = BooleanField(default=False)
is_active = BooleanField(default=True)
date_joined = DateTimeField(default=util.now)
last_login = DateTimeField(null=True)
class Usuarios(BaseModel):
usuario = TextField(unique=True)
nombre = TextField(default='')
apellidos = TextField(default='')
correo = TextField(default='')
contraseña = PasswordField()
es_superusuario = BooleanField(default=False)
es_admin = BooleanField(default=False)
es_activo = BooleanField(default=True)
fecha_ingreso = DateTimeField(default=util.now)
ultimo_ingreso = DateTimeField(null=True)
def __str__(self):
t = '{} {} ({})'
return t.format(self.first_name, self.last_name, self.username)
return t.format(self.nombre, self.apellidos, self.usuario)
class Meta:
order_by = ('username',)
order_by = ('nombre', 'apellidos')
class SATRegimenes(BaseModel):
key = TextField(index=True, unique=True)
name = TextField(index=True)
activo = BooleanField(default=False)
default = BooleanField(default=False)
fisica = BooleanField(default=False)
moral = BooleanField(default=False)
class Meta:
order_by = ('name',)
indexes = (
(('key', 'name'), True),
)
class Emisor(BaseModel):
rfc = TextField(index=True)
nombre = TextField()
codigo_postal = TextField(default='')
moral = BooleanField(default=False)
regimenes = ManyToManyField(SATRegimenes, related_name='emisores')
def __str__(self):
t = '{} ({})'
return t.format(self.nombre, self.rfc)
class Meta:
order_by = ('nombre',)
class Certificado(BaseModel):
key = BlobField()
key_enc = TextField(default='')
cer = BlobField()
cer_pem = TextField(default='')
cer_txt = TextField(default='')
p12 = BlobField()
serie = TextField(default='')
rfc = TextField(default='')
desde = DateTimeField()
hasta = DateTimeField()
def __str__(self):
return self.serie
class Clients(BaseModel):
@ -114,22 +162,23 @@ class ClientsTags(BaseModel):
)
def authenticate(username, password):
data = {'login': False, 'msg': 'No Autorizado', 'user': ''}
def authenticate(usuario, contraseña):
respuesta = {'login': False, 'msg': 'No Autorizado', 'user': ''}
try:
obj = Users.get(Users.username==username, Users.is_active==True)
except Users.DoesNotExist:
return data
obj = Usuarios.get(usuario=usuario, es_activo=True)
except Usuarios.DoesNotExist:
return respuesta
if not util.validate_password(obj.password, password):
return data
if not obj.contraseña.check_password(contraseña):
return respuesta
obj.last_login = util.now()
obj.ultimo_ingreso = util.now()
obj.save()
data['msg'] = ''
data['login'] = True
data['user'] = str(obj)
return data
respuesta['msg'] = ''
respuesta['login'] = True
respuesta['user'] = str(obj)
respuesta['super'] = obj.es_superusuario
return respuesta
def get_partners(values):
@ -199,12 +248,12 @@ def _init_values():
return
def create_tables():
connect()
tables = [Configuration, Tags, Users, Clients, ClientsTags]
database.create_tables(tables, True)
def _crear_tablas():
conectar()
tablas = [Configuracion, Tags, Usuarios,
Certificado, Emisor, Emisor.regimenes.get_through_model()]
database.create_tables(tablas, True)
log.info('Tablas creadas correctamente...')
_init_values()
return
@ -214,19 +263,20 @@ def migrate_tables():
return
def create_superuser():
connect()
username = input('Introduce el nuevo nombre para el superusuario: ').strip()
if not username:
def _agregar_superusuario():
conectar()
usuario = input('Introduce el nuevo nombre para el superusuario: ').strip()
if not usuario:
msg = 'El nombre de usuario es requerido'
log.erro(msg)
return
ok, password = util.get_pass()
ok, contraseña = util.get_pass()
if not ok:
log.error(password)
log.error(contraseña)
return
try:
obj = Users.create(username=username, password=password, is_superuser=True)
obj = Usuarios.create(
usuario=usuario, contraseña=contraseña, es_superusuario=True)
except IntegrityError:
msg = 'El usuario ya existe'
log.error(msg)
@ -236,27 +286,27 @@ def create_superuser():
return
def change_password():
connect()
username = input('Introduce el nombre de usuario: ').strip()
if not username:
def _cambiar_contraseña():
conectar()
usuario = input('Introduce el nombre de usuario: ').strip()
if not usuario:
msg = 'El nombre de usuario es requerido'
log.error(msg)
return
try:
obj = Users.get(username=username)
except Users.DoesNotExist:
obj = Usuarios.get(usuario=usuario)
except Usuarios.DoesNotExist:
msg = 'El usuario no existe'
log.error(msg)
return
ok, password = util.get_pass()
ok, contraseña = util.get_pass()
if not ok:
log.error(password)
log.error(contraseña)
return
obj.password = password
obj.contraseña = contraseña
obj.save()
log.info('Contraseña cambiada correctamente...')
@ -282,7 +332,7 @@ def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña):
opt = locals()
if opt['iniciar_bd']:
create_tables()
_crear_tablas()
sys.exit(0)
if opt['migrar_bd']:
@ -290,11 +340,11 @@ def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña):
sys.exit(0)
if opt['nuevo_superusuario']:
create_superuser()
_agregar_superusuario()
sys.exit(0)
if opt['cambiar_contraseña']:
change_password()
_cambiar_contraseña()
return

View File

@ -5,7 +5,7 @@ import os
import sys
from mako.lookup import TemplateLookup
from logbook import Logger, StreamHandler, RotatingFileHandler
logbook.set_datetime_format("local")
logbook.set_datetime_format('local')
from conf import DEBUG
@ -15,7 +15,7 @@ PATH_STATIC = os.path.abspath(os.path.join(BASE_DIR, '..'))
PATH_TEMPLATES = os.path.abspath(os.path.join(BASE_DIR, '..', 'templates'))
EMAIL_SUPPORT = ('soporte@empresalibre.net',)
WITH_LOGIN = True
#~ WITH_LOGIN = True
DB_CP = 'cp.db'
PATH_CP = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', DB_CP))

View File

@ -0,0 +1,21 @@
var controllers = {
init: function(){
//~ Admin
$$('menu_user').attachEvent('onMenuItemClick', menu_user_click)
}
}
function menu_user_click(id, e, node){
if (id == 1){
window.location = '/logout'
return
}
}
function cmd_home_click(){
window.location = '/main'
}

View File

@ -29,7 +29,7 @@ var controllers = {
$$("cmd_save_invoice").attachEvent("onItemClick", cmd_save_invoice_click);
$$("cmd_cancel_invoice").attachEvent("onItemClick", cmd_cancel_invoice_click);
get_partners()
//~ get_partners()
}
};

View File

@ -0,0 +1,72 @@
var menu_data = [
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
{id: 'app_emisor', icon: 'user-circle', value: 'Emisor'},
{id: 'app_cert', icon: 'key', value: 'Certificado'},
]
var sidebar = {
view: 'sidebar',
data: menu_data,
ready: function(){
this.select('app_home');
this.open(this.getParentId('app_home'));
},
on:{
onAfterSelect: function(id){
$$('multi').setValue(id)
}
}
};
var multi_main = {
id: 'multi',
animate: true,
cells:[
{
id: 'app_home',
view: 'template',
template: 'HOME'
}
//~ app_emisor,
]
};
var menu_user = {
view: 'menu',
id: 'menu_user',
width: 150,
autowidth: true,
data: [
{id: '0', value: 'User...', submenu:[{id:1, value:'Cerrar Sesión'}]},
],
type: {
subsign: true,
},
};
var ui_admin = {
rows: [
{view: 'toolbar', padding: 3, elements: [
{view: 'button', type: 'icon', icon: 'bars',
width: 37, align: 'left', css: 'app_button', click: function(){
$$('$sidebar1').toggle()
}
},
{view: 'label', label: 'Empresa Libre - Configuración'},
{},
{view: 'button', type: 'icon', width: 40, css: 'app_button',
icon: 'home', click: 'cmd_home_click'},
menu_user
]},
{
cols:[
sidebar,
multi_main,
]
}
]
};

View File

@ -1,12 +1,12 @@
var msg_user = 'El usuario es requerido'
var msg_pass = 'La contraseña es requerida'
var form_controls = [
{view: 'text', label: 'Usuario', name: 'user', labelPosition: 'top',
required: true, invalidMessage: msg_user},
{view: 'text', label: 'Contraseña', name: 'pass', type: 'password',
required: true, labelPosition: 'top', invalidMessage: msg_pass},
{view: 'text', label: 'Usuario', id: 'txt_usuario', name: 'usuario',
labelPosition: 'top', required: true, invalidMessage: msg_user},
{view: 'text', label: 'Contraseña', id: 'txt_contra', name: 'contra',
type: 'password', required: true, labelPosition: 'top',
invalidMessage: msg_pass},
{margin: 10, cols:[{}, {view: 'button', value: 'Iniciar Sesión',
click: 'validate_login', hotkey: 'enter'}, {}]}
]
@ -28,8 +28,8 @@ var ui_login = {
width: 400,
elements: form_controls,
rules:{
user:function(value){ return value.trim() != '';},
pass:function(value){ return value.trim() != '';},
usuario:function(value){ return value.trim() != '';},
contra:function(value){ return value.trim() != '';},
}
},
]}, {}, ]

View File

@ -1,5 +1,4 @@
var menu_data = [
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
{id: 'app_partners', icon: 'users', value: 'Clientes y Proveedores'},

View File

@ -0,0 +1,29 @@
<%inherit file="base.html"/>
<%block name="media">
<link rel="stylesheet" href="/static/css/sidebar_air.css" type="text/css">
<script src="/static/js/sidebar.js" type="text/javascript" ></script>
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
<script src="/static/js/ui/admin.js" type="text/javascript" ></script>
<script src="/static/js/controller/admin.js" type="text/javascript" ></script>
</%block>
<%block name="content">
<input type=hidden id="username" value="${username}"/>
<script type="text/javascript" charset="utf-8">
webix.ready(function(){
webix.CustomScroll.init()
webix.ui(ui_admin)
controllers.init()
var user = document.getElementById("username").value
$$('menu_user').getMenu(0).updateItem(0, {value:user})
})
</script>
</%block>

View File

@ -9,7 +9,6 @@
<link rel="stylesheet" href="/static/css/app.css" type="text/css">
<script src="/static/js/webix_debug.js" type="text/javascript" ></script>
<script src="/static/js/es-MX.js" type="text/javascript" ></script>
<%block name="media"/>
</head>

View File

@ -18,14 +18,18 @@ function validate_login(){
return
}
var values = form.getValues();
var values = form.getValues()
webix.ajax().post("/", values, function(text, data, xhr) {
var values = data.json();
if (values.login) {
window.location = "/main";
if (values.super) {
window.location = "/admin"
}else{
window.location = "/main"
}
} else {
webix.message({ type:"error", text: values.msg });
webix.message({ type:"error", text: values.msg })
}
});
};