diff --git a/app/auth/routes.py b/app/auth/routes.py index 5ef3da9..76f4651 100644 --- a/app/auth/routes.py +++ b/app/auth/routes.py @@ -35,6 +35,10 @@ def login(): if form.validate_on_submit(): user = User.query.filter_by(email=form.email.data).first() + if user.active == False: + flash('User disabled.') + return redirect(url_for('main.index')) + if user is not None and user.verify_password(form.password.data): if user.twofactor: # redirect to the two-factor auth page, passing username in session @@ -43,6 +47,7 @@ def login(): return redirect(url_for('auth.twofactor')) #print('remember: ' + str(form.remember_me.data)) login_user(user, form.remember_me.data) + previp = user.last_ip if request.headers.getlist("X-Forwarded-For"): lastip = request.headers.getlist("X-Forwarded-For")[0] else: @@ -51,8 +56,10 @@ def login(): db.session.add(user) db.session.commit() #send_email(current_app.config['MAIL_USERNAME'], user.email + ' logged in.', 'auth/email/adm_loginnotify', user=user, ipaddr=lastip ) + flash('Last Login: {} from {}'.format(user.last_seen, previp)) return redirect(request.args.get('next') or url_for('vmanager.dashboard')) - flash('Invalid username or password.') + else: + flash('Invalid username or password.') return render_template('auth/login.html', page=page, form=form) diff --git a/app/models.py b/app/models.py index d18f2ef..36d98d3 100644 --- a/app/models.py +++ b/app/models.py @@ -68,8 +68,9 @@ class User(db.Model, UserMixin): address = db.Column(db.Unicode(256)) city = db.Column(db.Unicode(64)) postcode = db.Column(db.String(10)) - country = db.Column(db.String(64)) + country = db.Column(db.String(64), default='BG') phone = db.Column(db.String(64)) + org_account = db.Column(db.Boolean, default=False) org_companyname = db.Column(db.Unicode(64)) org_regaddress = db.Column(db.Unicode(128)) org_responsible = db.Column(db.Unicode(128)) @@ -77,16 +78,15 @@ class User(db.Model, UserMixin): org_vat = db.Column(db.Boolean, default=False) org_vatnum = db.Column(db.String(16)) - wallet = db.Column(db.Float, default=0.0) - credit = db.Column(db.Float) - creditlimit = db.Column(db.Float, default=20.0) - - currency = db.Column(db.String(3), default='BGN') + group = db.Column(db.String(24), default='nogroup') language = db.Column(db.String(2), default='BG') + wallet = db.Column(db.Float, default=0.0) + currency = db.Column(db.String(3), default='BGN') inv_deployments = db.relationship('Deployment', backref='owner', lazy='dynamic') inv_contracts = db.relationship('Contract', backref='owner', lazy='dynamic') inv_domains = db.relationship('Domain', backref='owner', lazy='dynamic') + inv_address = db.relationship('Address', backref='owner', lazy='dynamic') def __init__(self, **kwargs): super(User, self).__init__(**kwargs) @@ -310,7 +310,106 @@ class Service(db.Model): } return services -#TRANSACTIONS + +#INVENTORY CLASSES +class Deployment(db.Model): + __tablename__ = 'deployments' + pid = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK + product_id = db.Column(db.Integer, db.ForeignKey('products.pid')) #FK + date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) + date_expire = db.Column(db.DateTime) + enabled = db.Column(db.Boolean) + + machine_id = db.Column(db.BigInteger) #cubeid + machine_alias = db.Column(db.String) #dns name + machine_cpu = db.Column(db.Integer) + machine_mem = db.Column(db.Integer) + machine_hdd = db.Column(db.Integer) + + def charge(): + result = Deployment.query.all() + for deploy in result: + if deploy.enabled == True: + managed_user = User.query.get(deploy.user_id) + db.session.add(managed_user) + current_product = Product.query.get(int(deploy.product_id)) + cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO'] + mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO'] + hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO'] + total = cpu_cost + mem_cost + hdd_cost + + if managed_user.wallet - total > 0: + managed_user.wallet -= total + print('{}> Charging deployment #{} with {}. Wallet now is: {}'.format(managed_user.email, deploy.machine_id, total, managed_user.walet)) + else: + print('{}> Deployment #{} cannot be charged with {}. Not enough money in the wallet ({}). Notifying admin...'.format(managed_user.email, deploy.machine_id, total, managed_user.wallet)) + #TODO: Send emails here. + db.session.commit() + +class Contract(db.Model): + __tablename__ = 'contracts' + pid = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK + service_id = db.Column(db.Integer, db.ForeignKey('services.pid')) #FK + date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) + date_expire = db.Column(db.DateTime) + enabled = db.Column(db.Boolean) + + description = db.Column(db.Unicode) + units = db.Column(db.Integer) + discount = db.Column(db.Integer) #percent + + def charge(): + result = Contract.query.all() + for contract in result: + managed_user = User.query.get(contract.user_id) + db.session.add(contract) + #if datetime.utcnow.date() > (contract.date_expire - timedelta(days=10)): + if contract.enabled == True: + print('{}> Contract {} will expire in 10 days at {}. Creating new order...'.format(managed_user.email, contract.pid, contract.date_expire)) + current_service = Service.query.get(int(contract.product_id)) + transaction = Transaction(user_id=managed_user.id, units=contract.units, unitvalue=(current_service.unitprice * contract.units), description=current_service.name) + db.session.add(transaction) + contract.data_expire = datetime.utcnow.date() + timedelta(days=30) + db.session.commit() + return True + +class Domain(db.Model): + __tablename__ = 'domains' + pid = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK + date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) + date_expire = db.Column(db.DateTime) + enabled = db.Column(db.Boolean) + + fqdn = db.Column(db.String, unique=True) + auto_update = db.Column(db.Boolean) + + def charge(): + result = Domain.query.all() + for domain in result: + managed_user = User.query.get(domain.user_id) + db.session.add(domain) + #if datetime.utcnow.date() > (domain.date_expire - timedelta(days=60)): + if domain.enabled == True: + print('{}> Domain {} will expire in 60 days at {}. Creating new order...'.format(managed_user.email, domain.fqdn, domain.date_expire)) + transaction = Transaction(user_id=managed_user.id, unitvalue=25, description=domain.fqdn) + db.session.add(transaction) + db.session.commit() + return True + +class Address(db.Model): + __tablename__ = 'address' + pid = db.Column(db.Integer, primary_key=True) + user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK + date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) + + ipaddr = db.Column(db.String(128)) + macaddr = db.Column(db.String(128)) + + +#UINVOICE class Transaction(db.Model): __tablename__ = 'transaction' pid = db.Column(db.Integer, primary_key=True) @@ -319,7 +418,6 @@ class Transaction(db.Model): currency = db.Column(db.String, default='BGN') value = db.Column(db.Float) -#PROFORMA INVOICE CLASS class Invoice(db.Model): __tablename__ = 'invoice' pid = db.Column(db.Integer, primary_key=True) @@ -362,93 +460,3 @@ class InvoiceItem(db.Model): def total(self): return self.item_quantity * self.item_price -#INVENTORY CLASSES -class Deployment(db.Model): - __tablename__ = 'deployments' - pid = db.Column(db.Integer, primary_key=True) - user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK - product_id = db.Column(db.Integer, db.ForeignKey('products.pid')) #FK - date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) - date_expire = db.Column(db.DateTime) - enabled = db.Column(db.Boolean) - - machine_id = db.Column(db.BigInteger) #cubeid - machine_alias = db.Column(db.String) #dns name - machine_cpu = db.Column(db.Integer) - machine_mem = db.Column(db.Integer) - machine_hdd = db.Column(db.Integer) - - def charge(): - result = Deployment.query.all() - for deploy in result: - if deploy.enabled == True: - managed_user = User.query.get(deploy.user_id) - db.session.add(managed_user) - current_product = Product.query.get(int(deploy.product_id)) - cpu_cost = deploy.machine_cpu * current_app.config['CPU_RATIO'] - mem_cost = ( deploy.machine_mem / 1024 ) * current_app.config['MEM_RATIO'] - hdd_cost = deploy.machine_hdd * current_app.config['HDD_RATIO'] - total = cpu_cost + mem_cost + hdd_cost - - if managed_user.wallet - managed_user.credit > managed_user.creditlimit: - print('{}> Deployment #{} costs {} today. Credit is now {}'.format(managed_user.email, deploy.machine_id, total, managed_user.credit)) - managed_user.credit += total - else: - print('{}> Deployment #{} costs {} today. Credit now is {} and its lower than the credit limit {}.'.format(managed_user.email, deploy.machine_id, total, managed_user.credit, managed_user.creditlimit)) - print('') - db.session.commit() - -class Contract(db.Model): - __tablename__ = 'contracts' - pid = db.Column(db.Integer, primary_key=True) - user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK - service_id = db.Column(db.Integer, db.ForeignKey('services.pid')) #FK - date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) - date_expire = db.Column(db.DateTime) - enabled = db.Column(db.Boolean) - - description = db.Column(db.Unicode) - units = db.Column(db.Integer) - discount = db.Column(db.Integer) #percent - credit = db.Column(db.Float) - - def charge(): - result = Contract.query.all() - for contract in result: - managed_user = User.query.get(contract.user_id) - db.session.add(contract) - #if datetime.utcnow.date() > (contract.date_expire - timedelta(days=10)): - if contract.enabled == True: - print('{}> Contract {} will expire in 10 days at {}. Creating new order...'.format(managed_user.email, contract.pid, contract.date_expire)) - current_service = Service.query.get(int(contract.product_id)) - transaction = Transaction(user_id=managed_user.id, units=contract.units, unitvalue=(current_service.unitprice * contract.units), description=current_service.name) - db.session.add(transaction) - contract.data_expire = datetime.utcnow.date() + timedelta(days=30) - db.session.commit() - return True - -class Domain(db.Model): - __tablename__ = 'domains' - pid = db.Column(db.Integer, primary_key=True) - user_id = db.Column(db.Integer, db.ForeignKey('users.pid')) #FK - date_created = db.Column(db.DateTime, index=True, default=datetime.utcnow) - date_expire = db.Column(db.DateTime) - enabled = db.Column(db.Boolean) - - fqdn = db.Column(db.String, unique=True) - auto_update = db.Column(db.Boolean) - credit = db.Column(db.Float) - - def charge(): - result = Domain.query.all() - for domain in result: - managed_user = User.query.get(domain.user_id) - db.session.add(domain) - #if datetime.utcnow.date() > (domain.date_expire - timedelta(days=60)): - if domain.enabled == True: - print('{}> Domain {} will expire in 60 days at {}. Creating new order...'.format(managed_user.email, domain.fqdn, domain.date_expire)) - transaction = Transaction(user_id=managed_user.id, unitvalue=25, description=domain.fqdn) - db.session.add(transaction) - db.session.commit() - return True - diff --git a/app/settings/forms.py b/app/settings/forms.py index 9efb0b3..6cbdb1c 100644 --- a/app/settings/forms.py +++ b/app/settings/forms.py @@ -43,8 +43,13 @@ class EditProfileAdminForm(FlaskForm): country = SelectField('Държава:', choices=clist) phone = DecimalField('Телефон:', [validators.DataRequired()]) - org_responsible = StringField('Отговорно Лице:') + org_account = StringField('Юридическо лице') + org_companyname = StringField('Име на фирма:') + org_regaddress = StringField('Адресна регистрация:') + org_responsible = StringField('Отговор)но Лице:') org_bulstat = StringField('БУЛСТАТ:') + org_vat = StringField('Регистрация по ДДС:') + org_vatnum = StringField('ДДС Номер:') submit = SubmitField('Обнови') def __init__(self, user, *args, **kwargs): diff --git a/app/settings/routes.py b/app/settings/routes.py index c1e0d64..4dd9f42 100644 --- a/app/settings/routes.py +++ b/app/settings/routes.py @@ -31,22 +31,32 @@ def profile(): current_user.postcode = form.postcode.data current_user.country = form.country.data current_user.phone = form.phone.data + current_user.org_account = form.org_account.data + current_user.org_companyname = form.org_companyname.data + current_user.org_regaddress = form.org_regaddress.data current_user.org_responsible = form.org_responsible.data current_user.org_bulstat = form.org_bulstat.data + current_user.org_vat = form.org_vat.data + current_user.org_vatnum = form.org_vatnum.data current_user.twofactor = form.twofactor.data db.session.add(current_user) db.session.commit() flash('Info Updated!') - form.twofactor.data = current_user.twofactor form.name.data = current_user.name form.address.data = current_user.address form.city.data = current_user.city form.postcode.data = current_user.postcode form.country.data = current_user.country form.phone.data = current_user.phone + form.org_account.data = current_user.org_account + form.org_companyname.data = current_user.org_companyname + form.org_regaddress.data = current_user.org_regaddress form.org_responsible.data = current_user.org_responsible form.org_bulstat.data = current_user.org_bulstat + form.org_vat = current_user.org_vat + form.org_vatnum = current_user.org_vatnum + form.twofactor.data = current_user.twofactor - return render_template('settings/profile.html', page=page, form=form) + return render_template('settings/profile.html', page=page, form=form, wallet=wallet) diff --git a/app/templates/settings/_sidebar.html b/app/templates/settings/_sidebar.html index d3ce7eb..3900634 100644 --- a/app/templates/settings/_sidebar.html +++ b/app/templates/settings/_sidebar.html @@ -3,7 +3,9 @@
{{ current_user.name }}

- 2-Factor: {{ current_user.twofactor }}
+ Group: {{ current_user.group }}
+ 2Factor: {{ current_user.twofactor }}
+ Wallet: {{ wallet }} {{ current_user.currency }}