# coding: utf-8
import validators
from flask import Blueprint, g, render_template, session, redirect, url_for
from flask import request, flash
from sshpubkeys import SSHKey
from SWSCloudCore.controllers.billing import ControllerBilling
from SWSCloudCore.controllers.common import ControllerMessagesEmail
from SWSCloudCore.controllers.users import ControllerAPI
from SWSCloudCore.controllers.users import ControllerSSHKey
from SWSCloudCore.controllers.users import ControllerUsers
from SWSCloudCore.controllers.users import ControllerUsersDetails
from SWSCloudCore.controllers.users import ControllerUsersRecoveryCodes
from SWSCloudCore import models
viewAccount = Blueprint('account', __name__, url_prefix='/account')
@viewAccount.route('/', methods=['GET', 'POST'])
def index():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
cud = ControllerUsersDetails(session['user_id'])
# проверяем, есть ли запись в таблице usersdetails, чтобы небыло ошибок
if not cud.details_exists():
# если нет, то делаем запись в таблицу, чтобы небыло ошибок
cud.details_create()
return render_template(
'default/id/index.html',
user=cud.details_get(),
user_details=cud.details_get()
)
@viewAccount.route('/edit.html', methods=['GET', 'POST'])
def edit():
cu = ControllerUsers()
# check session
if not cu.check_session():
return redirect(url_for("account.logout"))
# auth user
if not cu.auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
cud = ControllerUsersDetails(session['user_id'])
# Проверяем есть ли детали пользователя.
if not cud.details_exists():
# Если нет, то создаём
cud.details_create()
if request.method == "POST":
if not request.form['zipcode'].isdigit():
flash(u'Индекс должен содержать только цифры')
return redirect(url_for('account.edit'))
cud.details_update(
fname=request.form['fname'],
lname=request.form['lname'],
address=request.form['address'],
city=request.form['city'],
country=request.form['country'],
state=request.form['state'],
zipcode=request.form['zipcode']
)
return redirect(url_for('account.edit'))
return render_template(
'default/id/edit.html',
user=cud.details_get(),
user_details=cud.details_get()
)
@viewAccount.route('/settings', methods=['GET', 'POST'])
def settings():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
return render_template(
'default/id/index.html',
user_details=ControllerUsers(session['user_id']).get()
)
@viewAccount.route('/billing', methods=['GET', 'POST'])
def billing():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
user_id = session['user_id']
cub = ControllerBilling()
if not cub.exists(user_id):
cub.create(user=user_id, balance=0)
# TODO: move to function
user_details = models.Users.select().where(
models.Users.id == session['user_id']
).get()
return render_template(
'default/id/balance.html',
user_details=user_details,
user_balance=cub.get(user_id),
history=cub.transactions_get(user_id)
)
@viewAccount.route('/registration.html', methods=['GET', 'POST'])
def registration():
cu = ControllerUsers()
# Проверяем сессию, если все данные на месте,
# то перенаправляем пользователя на страницу со списком контейнеров
if cu.check_session():
return redirect(url_for("containers.index"))
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
password2 = request.form['password2']
# Проверка введён ли проверочный пароль одинаково
if password != password2:
flash(u'Пароли не совпадают', 'error')
# Проверяем правильность адреса е-почты и
if not validators.email(email):
flash(u'Неправильный адрес електронной почты', 'error')
return redirect(url_for('account.registration'))
# Проверяем зарегистрирован ли указанный адрес електронной почты
if cu.user_exists_by_email(email):
flash(u'Польщователь с указанным адресом уже зарегистрирован')
return redirect(url_for('account.registration'))
# Регистрируем пользователя в системе
if ControllerUsers().registration(email, password):
user_id = ControllerUsers().get_id_by_email(email)
ControllerUsersDetails(user_id).details_create()
ControllerBilling().create(user_id, g.settings['bonus'])
# ControllerU
# send mail message with recovery code
message = u"""
Е-почта: %s
Пароль: %s
""" % (request.form['email'], request.form['password'])
subject = u'GoCloud.ru: Успешная регистрация'
lead = u"""
Поздравляем с успешной зарегистрацией.
"""
callout = u"""
Для входа в личный кабинет воспользуйтесь
страницей авторизации.
"""
email = ControllerMessagesEmail()
email.send(title=subject, to=request.form['email'], lead=lead, message=message, callout=callout)
# redirect to login page
flash(u'Учетная запись успешно зарегистрирована.', 'success')
return redirect(url_for('account.login'))
else:
flash('Ошибка при регистрации, попробуйте снова', 'error')
return redirect(url_for('account.registration'))
return render_template('default/id/registration.html')
@viewAccount.route('/login.html', methods=['GET', 'POST'])
def login():
cu = ControllerUsers()
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
# validation entered data
if not validators.email(email):
flash(u'Неправильный адрес електронной почты', 'error')
return redirect(url_for('account.login'))
# try auth only active users (with status code 1)
if cu.auth(email, password, 1):
# get user_id
user_id = cu.get_id_by_email(email)
# save user data to session
session['user_id'] = user_id
session['email'] = email
session['password'] = password
# redirect to rules list
return redirect(url_for('containers.index'))
else:
flash(u'Не авторизованы', 'error')
return redirect(url_for('account.login'))
return render_template("default/id/login.html")
@viewAccount.route('/logout.html')
def logout():
session.pop('user_id', None)
session.pop('email', None)
session.pop('password', None)
return redirect(url_for('account.login'))
@viewAccount.route("/password_reset.html", methods=['GET', 'POST'])
def password_reset():
if request.method == "POST":
cu = ControllerUsers()
curc = ControllerUsersRecoveryCodes()
email = request.form['email']
if not validators.email(email):
flash(u'Произошла ошибка. Введите корректный адрес е.почты.')
return redirect(url_for('account.password_reset'))
# check exists email
if not cu.user_exists_by_email(email):
flash(u'Произошла ошибка. Введите корректный адрес е.почты.')
return redirect(url_for('account.password_reset'))
# get user_id by email
user_id = str(cu.user_id_by_email(email))
# create recovery code
recovery_code = curc.code_generate()
# remove old recovery codes for user
curc.delete(user_id)
# write new recovery code to database
curc.create(user_id, recovery_code)
# send mail message with recovery code
subject = u'GoCloud.ru: Код восстановления доступа'
message = u'Код восстановления: %s' % recovery_code
lead = u"""
Данный код необходимо ввести на странице подтверждения
сброса пароля.
"""
callout = u'Если вы не хотите сбрасывать пароль, то просто проигнорируйте (или удалите) данное письмо.'
# controllers.Mail().send(request.form['email'], subject, message)
email = ControllerMessagesEmail()
email.send(title=subject, to=request.form['email'], lead=lead, message=message, callout=callout)
# redirect to step 2
flash(u'На указанный адрес был отправлен код подтверждения', 'info')
return redirect(url_for('account.password_reset_step2'))
return render_template('default/id/password_reset_step1.html')
@viewAccount.route("/password_reset_step2.html", methods=['GET', 'POST'])
def password_reset_step2():
if request.method == "POST":
# check exists email
if ControllerUsers().user_exists_by_email(request.form['email']):
# get user_id by email
user_id = ControllerUsers().user_id_by_email(request.form['email'])
recovery_code = request.form['recovery_code']
# check valid recovery codes
if ControllerUsersRecoveryCodes().check(user_id, recovery_code):
# remove old recovery codes for user
ControllerUsersRecoveryCodes().delete(user_id)
# generate new password
new_password = ControllerUsers().generate_password()
# save password
ControllerUsers().update(user_id, password=new_password)
# send mail message with new password
message = u"""Новый пароль: %s""" % new_password
subject = u"""GoCloud.ru: Новый пароль"""
lead = u"""
Пароль для доступа в личный кабинет был сброшен.
"""
callout = u"""Запомните новый пароль и удалите данное сообщение."""
# controllers.Mail().send(request.form['email'], subject, message)
email = ControllerMessagesEmail()
email.send(title=subject, to=request.form['email'], lead=lead, message=message, callout=callout)
# redirect to login page
return redirect(url_for('account.login'))
# redirect to step 2
g.errors['items'].append(u'Ошибочный код')
g.errors['total'] += 1
return redirect(url_for('account.password_reset_step2'))
else:
g.errors['items'].append(u'Произошла ошибка. Введите корректный адрес е.почты.')
g.errors['total'] += 1
return render_template('default/id/password_reset_step2.html')
@viewAccount.route("/password_update", methods=['GET', 'POST'])
def password_update():
"""
Обновление пароля из личного кабинета с уведомлением владельца по ел.почте
:return:
"""
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
if request.method == "POST":
# Проверка старого пароля
check_old = ControllerUsers().auth(session['email'], request.form['old_password'])
if check_old and request.form['new_password'] == request.form['new_password_confirm']:
# Обновляем пароль
ControllerUsers().update(session['user_id'], password=request.form['new_password'])
# send mail message with recovery code
lead = u"""
Пароль для достуна в личный кабинет был успешно изменён.
"""
message = u"""Пароль: %s""" % request.form['new_password']
callout = u"""
"""
subject = u'GoCloud.ru: Смена пароля'
email = ControllerMessagesEmail()
email.send(
title=subject,
to=session['email'],
lead=lead,
message=message,
callout=callout
)
return redirect(url_for('account.password_update'))
return render_template('default/id/password_update.html')
@viewAccount.route('/sshkey', methods=['GET', 'POST'])
def sshkey():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
controllersshkey = ControllerSSHKey(session['user_id'])
if request.method == "POST":
try:
ssh = SSHKey(request.form['sshkey'])
except Exception as e:
g.errors['items'].append(u"Не корректный ssh-ключ.")
g.errors['total'] += 1
else:
print(ssh.bits)
print(ssh.hash())
controllersshkey.set(request.form['sshkey'])
sshkey = {
"exists": controllersshkey.check(),
"sshkey": controllersshkey.get()
}
return render_template('default/id/sshkey.html', sshkey=sshkey)
@viewAccount.route('/sshkey_delete', methods=['POST'])
def sshkey_delete():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
controllersshkey = ControllerSSHKey(session['user_id'])
controllersshkey.delete()
return redirect(url_for('account.sshkey'))
@viewAccount.route('/api', methods=['GET', 'POST'])
def api():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
#
if not ControllerAPI().check(session['user_id']):
ControllerAPI().set(session['user_id'], '', '', 0)
#
user_secret = ControllerAPI().get(session['user_id'])[0]
return render_template(
'default/id/api.html',
user_secret=user_secret
)
@viewAccount.route('/api_update', methods=['POST'])
def api_update():
# check session
if not ControllerUsers().check_session():
return redirect(url_for("account.logout"))
# auth user
if not ControllerUsers().auth(session['email'], session['password']):
return redirect(url_for("account.logout"))
#
ControllerAPI().set(
session['user_id'],
request.form['secret'],
request.form['acl'],
request.form['status']
)
#
return redirect(url_for('account.api'))