refactoting and new apiv2

This commit is contained in:
Vyacheslav Anzhiganov 2017-01-18 11:07:29 +03:00
parent ef3933802e
commit 9261b24730
29 changed files with 563 additions and 166 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,35 +0,0 @@
# coding: utf-8
from flask import Blueprint, jsonify, g
from flask_httpauth import HTTPBasicAuth
from SWSCloudCore.controllers.users import ControllerAPI
from SWSCloudCore.controllers.users import ControllerUsers
api = Blueprint('api', __name__, url_prefix='/api/v1')
auth = HTTPBasicAuth()
"""
TODO: Реализовать Процесс авторизации в версии API 2.0
- получаем емейл и секретный ключ
- создаём временный токен
- выдаём токен
"""
@auth.verify_password
def verify_password(username, password):
if not ControllerAPI().auth(username, password):
return False
g.user_id = ControllerUsers().get_id_by_email(username)
return True
@api.route('/')
@auth.login_required
def index():
"""
curl -X POST http://localhost:5000/api/v1/ -u <email>:<secret>
:return:
"""
return jsonify(user_id=g.user_id)

View file

View file

@ -0,0 +1 @@
# coding: utf-8

View file

@ -0,0 +1,17 @@
# coding: utf-8
from flask import Blueprint, jsonify, g
from SWSCloudAPI.API.compute.v1.common import auth
api_v1 = Blueprint('api', __name__, url_prefix='/api/compute/v1')
@api_v1.route('/')
@auth.login_required
def index():
"""
curl -X POST http://localhost:5000/api/v1/ -u <email>:<secret>
:return:
"""
return jsonify(user_id=g.user_id)

View file

@ -0,0 +1,15 @@
from SWSCloudCore.controllers.users import ControllerAPI
from SWSCloudCore.controllers.users import ControllerUsers
from flask_httpauth import HTTPBasicAuth
auth = HTTPBasicAuth()
@auth.verify_password
def verify_password(username, password):
if not ControllerAPI().auth(username, password):
return False
g.user_id = ControllerUsers().get_id_by_email(username)
return True

View file

@ -2,7 +2,7 @@
from uuid import uuid4
from flask import Blueprint, jsonify, request, g
from SWSCloudAPI.API import auth
from SWSCloudAPI.API.compute.v1.common import auth
from SWSCloudCore.controllers.datacenters import ControllerDataCenters
from SWSCloudCore.controllers.ips import ControllerIps
from SWSCloudCore.controllers.users import ControllerUsers
@ -13,7 +13,7 @@ from SWSCloudCore.controllers.tasks import ControllerTasks
from SWSCloudCore.controllers.containers import (
ControllerContainers, ControllerContainersStatistics, ControllerContainersStatisticsState)
api_v1_containers = Blueprint('containers', __name__, url_prefix='/api/v1/containers')
api_v1_containers = Blueprint('containers', __name__, url_prefix='/api/compute/v1/containers')
@api_v1_containers.route('/', methods=['GET'])

View file

@ -0,0 +1,24 @@
# coding: utf-8
from flask import Blueprint, jsonify
from SWSCloudAPI.API.compute.v1.common import auth
from SWSCloudCore.models import DataCenters
api_v1_datacenters = Blueprint('datacenters', __name__, url_prefix='/api/compute/v1/datacenters')
@api_v1_datacenters.route('/', methods=['GET'])
@auth.login_required
def index():
"""
get containers list
curl -X http://localhost:5000/api/compute/v1/datacenters/ -u <email>:<secret>
:return:
"""
# dc_list = ControllerDataCenters().get()
dc_list = DataCenters.get_available()
items = list()
for x in dc_list:
items.append(x)
return jsonify(total=len(dc_list), items=items)

View file

@ -1,13 +1,13 @@
# coding: utf-8
from flask import Blueprint, jsonify
from SWSCloudAPI.API import auth
from SWSCloudAPI.API.compute.v1.common import auth
from SWSCloudCore.controllers.plans import ControllerPlans
api_v1_pricing = Blueprint('pricing', __name__, url_prefix='/api/v1/pricing')
api_v1_pricing = Blueprint('pricing', __name__, url_prefix='/api/compute/v1/pricing')
@api_v1_pricing.route('/pricing/vms/')
@api_v1_pricing.route('/vms')
@auth.login_required
def pricing_vms():
"""
@ -18,7 +18,7 @@ def pricing_vms():
return jsonify(pricing=ControllerPlans().get_plans(status='active'))
@api_v1_pricing.route('/pricing/containers/')
@api_v1_pricing.route('/containers')
@auth.login_required
def pricing_containers():
"""

View file

@ -2,7 +2,7 @@
from uuid import uuid4
from flask import Blueprint, jsonify, request, g
from SWSCloudAPI.API import auth
from SWSCloudAPI.API.compute.v1.common import auth
from SWSCloudCore.controllers.ips import ControllerIps
from SWSCloudCore.controllers.plans import ControllerPlans
from SWSCloudCore.controllers.users import ControllerUsers
@ -12,7 +12,7 @@ from SWSCloudCore.controllers.common import ControllerCommon, ControllerMessages
from SWSCloudCore.controllers.tasks import ControllerTasks
from SWSCloudCore.controllers.vms import ControllerVMS
api_v1_vms = Blueprint('vms', __name__, url_prefix='/api/v1/vms')
api_v1_vms = Blueprint('vms', __name__, url_prefix='/api/compute/v1/vms')
@api_v1_vms.route('/', methods=['GET'])

View file

View file

@ -0,0 +1,3 @@
TOKEN_TTL = 1800
TOKEN_PREFIX = 'token_'

View file

@ -0,0 +1,33 @@
# coding: utf-8
from flask import Blueprint, jsonify, request, g
from SWSCloudAPI.API.compute.v2.common import *
from SWSCloudCore.models import DataCenters
api_v2_datacenters = Blueprint('v2datacenters', __name__, url_prefix='/api/compute/v2/datacenters')
@api_v2_datacenters.route('/', methods=['GET'])
def datacenter_list():
"""
get containers list
curl -X http://localhost:5000/api/compute/v1/datacenters/ -u <email>:<secret>
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
#
dc_list = DataCenters.get_available()
items = list()
for x in dc_list:
items.append(x)
return jsonify(status='ok', payload=items, total=len(dc_list))

View file

@ -0,0 +1,28 @@
# coding: utf-8
from flask import Blueprint, jsonify, request, g
from SWSCloudAPI.API.compute.v2.common import *
from SWSCloudCore.controllers.plans import ControllerPlans
api_v2_pricing = Blueprint('v2pricing', __name__, url_prefix='/api/compute/v2/pricing')
@api_v2_pricing.route('/')
def pricing():
"""get pricing list
curl -XGET http://localhost:5001/api/compute/v2/pricing/ -H "X-Auth-Token: ad89abee-49bc-4434-98ee-c7598c2f0adc" -H "Content-Type: application/json"
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
payload = ControllerPlans().get_plans(status='active')
return jsonify(status='ok', payload=payload)

View file

@ -0,0 +1,65 @@
# coding: utf-8
import json
import validators
from uuid import uuid4
from flask import Blueprint, jsonify, g, request
from SWSCloudCore.models import Users
from SWSCloudAPI.API.compute.v2.common import *
api_v2_token = Blueprint('v2token', __name__, url_prefix='/api/compute/v2/token')
@api_v2_token.route('/', methods=['POST'])
def token_post():
"""Get token
_Example_
curl -XPOST http://localhost:5001/api/compute/v2/token/ -d '{"email":"vanzhiganov@ya.ru","password":"qwepoi123"}' -H "Content-Type: application/json"
{
"status": "ok",
"token": "422f45a4-eab9-4a79-9954-61c568bae0eb"
}
:return:
"""
#
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# validate email
if not validators.email(request.json.get('email')):
return jsonify(status='fail', message='invalid email format')
# verify email/password
if not Users.auth(request.json.get('email'), request.json.get('password')):
return jsonify(status='fail', message='invalid auth')
# get user data
user = Users.get_by_email(request.json.get('email'))
token = str(uuid4())
g.tokens.set(TOKEN_PREFIX + token, json.dumps(dict(user_id=str(user.id))), TOKEN_TTL)
return jsonify(status='ok', payload=dict(token=token))
@api_v2_token.route('/', methods=['GET'])
def token_get():
"""Get token data
curl -XGET http://localhost:5001/api/compute/v2/token/ -H "X-Auth-Token: 422f45a4-eab9-4a79-9954-61c568bae0eb" -H "Content-Type: application/json"
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
return jsonify(
status='ok',
# ttl=g.tokens.ttl('token_'+request.headers.get('X-Auth-Token')),
# pttl=g.tokens.pttl('token_'+request.headers.get('X-Auth-Token')),
payload=json.loads(g.tokens.get(TOKEN_PREFIX + request.headers.get('X-Auth-Token')))
)

View file

@ -0,0 +1,290 @@
# coding: utf-8
import json
from uuid import uuid4
from flask import Blueprint, jsonify, request, g
from SWSCloudAPI.API.compute.v2.common import *
from SWSCloudCore.controllers.ips import ControllerIps
from SWSCloudCore.controllers.plans import ControllerPlans
from SWSCloudCore.controllers.users import ControllerUsers
from SWSCloudCore.controllers.users import ControllerSSHKey
from SWSCloudCore.controllers.billing import ControllerBilling
from SWSCloudCore.controllers.common import ControllerCommon, ControllerMessagesEmail
from SWSCloudCore.controllers.tasks import ControllerTasks
from SWSCloudCore.controllers.vms import ControllerVMS
api_v2_vms = Blueprint('v2vms', __name__, url_prefix='/api/compute/v2/vms')
@api_v2_vms.route('/', methods=['GET'])
def vms_list():
"""
get virtual servers list
curl -X POST http://localhost:5000/api/v1/vms/ -u <email>:<secret>
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
user = json.loads(g.tokens.get(TOKEN_PREFIX + request.headers.get('X-Auth-Token')))
return jsonify(status='ok', payload=ControllerVMS(user.get('user_id')).get_items())
@api_v2_vms.route('/', methods=['POST'])
def vms_create():
"""
curl -XPOST /api/v1/vms/ -u <email>:<secret> -d 'plan=<uuid>&datacenter=<uuid>'
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
user = json.loads(g.tokens.get(TOKEN_PREFIX + request.headers.get('X-Auth-Token')))
#
user_balance = ControllerBilling().get(user.get('user_id'))
user_ssh = ControllerSSHKey(user.get('user_id'))
controller_plans = ControllerPlans()
# check user money
if user_balance <= 0:
return jsonify(status='error', message='no money')
new_vm = dict()
new_vm['vm_id'] = str(uuid4())
# check exists plan
if not controller_plans.exists(request.json.get('plan')):
return jsonify(message='plan not exists')
# load plan details
plan_details = controller_plans.plan_get(request.json.get('plan'))
new_vm['plan'] = request.json.get('plan')
# select server from selected region with available ip-addresses
# select IP
select_ip = ControllerIps().getfree(request.json.get('datacenter'))
# mark ip as busy (taken)
ControllerIps().setbusy(select_ip.id)
# generate password for container user
new_vm['password'] = ControllerCommon().generate_password(size=14)
new_vm['hostname'] = ControllerCommon().generate_password(size=7)
new_vm['datacenter_id'] = str(select_ip.datacenter.id)
new_vm['server_id'] = str(select_ip.server.id)
new_vm['platform'] = 'x86_64'
new_vm['ipv4'] = select_ip.ipv4
new_vm['ipv6'] = select_ip.ipv6
new_vm['ipv4_gateway'] = select_ip.ipv4_gateway
new_vm['ipv6_gateway'] = select_ip.ipv6_gateway
# TODO: remove hardcore
new_vm['dns1'] = '8.8.8.8'
new_vm['dns2'] = '8.8.4.4'
new_vm['cores'] = plan_details.cores
new_vm['storage'] = plan_details.storage
new_vm['swap'] = plan_details.swap
new_vm['memory'] = plan_details.memory
new_vm['os_name'] = 'ubuntu'
new_vm['os_suite'] = 'trusty'
# sshkey
new_vm['ssh_key'] = None
if user_ssh.check():
new_vm['ssh_key'] = user_ssh.get()
# create container record in database
# status 4: creation
status = 4
container_create = ControllerVMS(user.get('user_id')).create(
vm_id=new_vm['vm_id'],
datacenter_id=new_vm['datacenter_id'],
server_id=new_vm['server_id'],
hostname=new_vm['hostname'],
ipv4=new_vm['ipv4'],
ipv6=new_vm['ipv6'],
plan=new_vm['plan'],
platform=new_vm['platform'],
os_name=new_vm['os_name'],
os_suite=new_vm['os_suite'],
status=status
)
# create default state data
# ControllerContainersStatisticsState().set(new_container['container_id'], dict())
if not container_create:
# mark ip as free
ControllerIps().setfree(select_ip.id)
return jsonify(status='error', message='fail')
# create task for create new container
ControllerTasks(user.get('user_id')).create(
new_vm['datacenter_id'],
new_vm['server_id'],
'vm_create',
0,
vm_id=new_vm['vm_id'],
ipv4=new_vm['ipv4'],
ipv4_gateway=new_vm['ipv4_gateway'],
ipv6=new_vm['ipv6'],
ipv6_gateway=new_vm['ipv6_gateway'],
password=new_vm['password'],
hostname=new_vm['hostname'],
platform=new_vm['platform'],
# TODO: remove hardcore
dns1=new_vm['dns1'],
dns2=new_vm['dns2'],
cores=new_vm['cores'],
storage=new_vm['storage'],
swap=new_vm['swap'],
memory=new_vm['memory'],
os_name=new_vm['os_name'],
os_suite=new_vm['os_suite'],
ssh_key=new_vm['ssh_key'],
)
# send mail message with recovery code
message_parts = []
if new_vm['ipv4']:
message_parts.append(u"IPv4: %s" % new_vm['ipv4'])
if new_vm['ipv6']:
message_parts.append(u"IPv6: %s" % new_vm['ipv6'])
message_parts.append(u"Пользователь: %s" % 'administrator')
# message_parts.append(u"Пользователь: %s" % new_vm['username'])
message_parts.append(u"Пароль: %s" % new_vm['password'])
if new_vm['ssh_key']:
message_parts.append(u"SSH ключ: добавлен")
message = '<br/>\n'.join(message_parts)
subject = u'GoCloud.ru: Новый виртуальный сервер'
lead = u"""Поздравляем с новым виртуальным сервером."""
callout = u"""
Для входа в личный кабинет воспользуйтесь
<a href="https://gocloud.ru/account/login">страницей авторизации</a>.
"""
user_data = ControllerUsers(user.get('user_id')).get()
email = ControllerMessagesEmail()
email.send(title=subject, to=user_data.email, lead=lead, message=message, callout=callout)
return jsonify(
status=0, message='ok',
user='root', password=new_vm['password'], ipv4=new_vm['ipv4'],
public_ssh_key='added' if new_vm['ssh_key'] else 'empty')
@api_v2_vms.route('/<uuid:vm_id>', methods=['POST'])
def vm_actions(vm_id):
"""
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
user = json.loads(g.tokens.get(TOKEN_PREFIX + request.headers.get('X-Auth-Token')))
# init ...
vm = ControllerVMS(user.get('user_id'))
# get container details
vm_details = vm.get(vm_id=vm_id)
if request.json.get('action') == "start":
if ControllerBilling().get(user.get('user_id')) <= 0:
return jsonify(message='no money')
vm.set_status(vm_id, 2)
# Создание задания
ControllerTasks(user.get('user_id')).create(
datacenter_id=vm_details.datacenter.id,
server_id=vm_details.server.id,
task='vm_start',
status=0,
vm_id=vm_details.id
)
if request.json.get('action') == "restart":
return jsonify(message='not supported')
if request.json.get('action') == "stop":
vm.status_set(vm_id, 3)
# Создание задания
ControllerTasks(user.get('user_id')).create(
vm_details.datacenter.id,
vm_details.server.id,
'vm_stop',
0,
vm_id=vm_id
)
@api_v2_vms.route('/<uuid:vm_id>', methods=['DELETE'])
def vm_delete(vm_id):
"""
Удаление виртуального сервера
:param vm_id:
:return:
"""
if request.headers.get('Content-Type') != 'application/json':
return jsonify(status='fail', message='content-type must be application/json')
# check exists token
if not g.tokens.exists(TOKEN_PREFIX + request.headers.get('X-Auth-Token')):
return jsonify(status='fail', message='token not exists')
# TODO: move to different endpoint
g.tokens.expire(TOKEN_PREFIX + request.headers.get('X-Auth-Token'), TOKEN_TTL)
user = json.loads(g.tokens.get(TOKEN_PREFIX + request.headers.get('X-Auth-Token')))
#
vms = ControllerVMS(user.get('user_id'))
tasks = ControllerTasks(user.get('user_id'))
# check the user have a selected rule
# if user not have a container then redirect to the container list
if not vms.exists(vm_id):
return jsonify(message='not exists')
# get container details
vm_details = vms.get(vm_id)
# Обновляем статус "5" для правила
vms.set_status(vm_id, 5)
# Создание задания
tasks.create(
datacenter_id=vm_details.datacenter.id,
server_id=vm_details.server.id,
task='vm_delete',
status=0,
vm_id=vm_id,
# hostname=vm_details.hostname
)
return jsonify(status=0, message='ok')

View file

@ -1,20 +0,0 @@
# coding: utf-8
from flask import Blueprint, jsonify
from SWSCloudAPI.API import auth
from SWSCloudCore.controllers.datacenters import ControllerDataCenters
api_v1_datacenters = Blueprint('datacenters', __name__, url_prefix='/api/v1/datacenters')
@api_v1_datacenters.route('/', methods=['GET'])
@auth.login_required
def index():
"""
get containers list
curl -X http://localhost:5000/api/v1/datacenters/ -u <email>:<secret>
:return:
"""
dc_list = ControllerDataCenters().get()
return jsonify(total=dc_list.get('total'), items=dc_list.get('items'))

View file

@ -1,14 +1,21 @@
# coding: utf-8
import redis
from SWSCloudAPI.API.compute.v1.datacenters import api_v1_datacenters
from SWSCloudAPI.API.compute.v1.containers import api_v1_containers
from SWSCloudAPI.API.compute.v1.pricing import api_v1_pricing
from SWSCloudAPI.API.compute.v1.vms import api_v1_vms
from SWSCloudAPI.API.compute.v2.token import api_v2_token
from SWSCloudAPI.API.compute.v2.pricing import api_v2_pricing
from SWSCloudAPI.API.compute.v2.datacenters import api_v2_datacenters
from SWSCloudAPI.API.compute.v2.vms import api_v2_vms
from flask import Flask, g, jsonify
from SWSCloudAPI.API import api
from SWSCloudAPI.API.vms import api_v1_vms
from SWSCloudAPI.API.containers import api_v1_containers
from SWSCloudAPI.API.datacenters import api_v1_datacenters
from SWSCloudAPI.API.pricing import api_v1_pricing
from SWSCloudCore import models
from SWSCloudCore.models import database
from SWSCloudCore.config import config
from SWSCloudCore.models import database
app = Flask(__name__)
# Думал, что получится сделать автопрефик для всего приложения, но это не сработало
@ -17,39 +24,42 @@ app = Flask(__name__)
app.config['DEBUG'] = config.getboolean('Application', 'DEBUG')
app.config['SECRET_KEY'] = config.get("Application", "SECRET_KEY")
app.register_blueprint(api)
app.register_blueprint(api_v1_vms)
app.register_blueprint(api_v1_containers)
app.register_blueprint(api_v1_pricing)
app.register_blueprint(api_v1_datacenters)
app.register_blueprint(api_v2_token)
app.register_blueprint(api_v2_pricing)
app.register_blueprint(api_v2_datacenters)
@app.errorhandler(404)
def page_not_found(e):
app.logger.error(e)
return jsonify(dict(message='resource not found')), 404
return jsonify(status='error', message='resource not found')
@app.errorhandler(403)
def access_deny(e):
app.logger.error(e)
return jsonify(dict(message='access deny')), 403
return jsonify(status='error', message='access deny'), 403
@app.errorhandler(410)
def page_not_found(e):
app.logger.error(e)
return jsonify(dict()), 410
return jsonify({})
@app.errorhandler(500)
def page_not_found(e):
app.logger.error(e)
return jsonify(dict(message='maintenance')), 500
return jsonify(status='maintenance')
@app.before_request
def before_request():
g.tokens = redis.StrictRedis(config.get('Redis', 'host'), config.get('Redis', 'port'), config.get('Redis', 'db'))
g.settings = dict()
# извлекаем настройки и определяем их в глобальную переменную
for setting in models.Settings.select(models.Settings.key, models.Settings.val).execute():

View file

@ -21,35 +21,38 @@ from SWSCloudCore import models
viewAdministrator = Blueprint('administrator', __name__, url_prefix='/administrator')
@viewAdministrator.route('/login.html', methods=['GET', 'POST'])
@viewAdministrator.route('/login.html', methods=['GET'])
def login():
if request.method == 'POST':
admin_email = request.form.get('email').encode('utf-8')
admin_password = request.form.get('password').encode('utf-8')
# validation entered data
if not validators.email(admin_email):
flash('Invalid registration data')
return redirect(url_for('administrator.login'))
# try auth only active users (with status code 1)
if models.Admins.auth(admin_email, admin_password, 1):
# get user_id
user_id = ControllerAdministrators().get_id_by_email(admin_email)
# save user data to session
session['admin_id'] = str(user_id)
session['admin_email'] = admin_email
session['admin_password'] = admin_password
# redirect to rules list
return redirect(url_for('administrator.dashboard'))
else:
flash('Invalid login. Please try again.')
return redirect(url_for('administrator.login'))
return render_template('administrator/login.html')
@viewAdministrator.route('/login.html', methods=['POST'])
def login_post():
admin_email = request.form.get('email').encode('utf-8')
admin_password = request.form.get('password').encode('utf-8')
# validation entered data
if not validators.email(admin_email):
flash('Invalid registration data')
return redirect(url_for('administrator.login'))
# try auth only active users (with status code 1)
if not models.Admins.auth(admin_email, admin_password, 1):
flash('Invalid login. Please try again.')
return redirect(url_for('administrator.login'))
# get user_id
user_id = ControllerAdministrators().get_id_by_email(admin_email)
# save user data to session
session['admin_id'] = str(user_id)
session['admin_email'] = admin_email
session['admin_password'] = admin_password
# redirect to rules list
return redirect(url_for('administrator.dashboard'))
@viewAdministrator.route('/logout.html')
def logout():
session.pop('admin_id', None)

View file

@ -14,8 +14,8 @@
</div>
{% endif %}
{% endwith %}
<form action="{{ url_for('administrator.login') }}" method="post">
<label for="email">email</lable>
<form action="{{ url_for('administrator.login_post') }}" method="post">
<label for="email">email</label>
<input type="text" name="email" value="" id="email" />
<label for="password">password</label>
<input type="password" name="password" value="" id="password" />

View file

@ -42,6 +42,16 @@ class DataCenters(PgSQLModel):
city = CharField()
status = IntegerField(default=0)
@staticmethod
def get_available():
return DataCenters.select().where(
DataCenters.status == 1 and
DataCenters.id << Servers.select(Servers.datacenter).where(
Servers.status == 1 and
Servers.id << Ips.select(Ips.server).where(
Ips.status == 0).group_by(Ips.server)
).group_by(Servers.datacenter)).execute()
class Servers(PgSQLModel):
id = UUIDField(unique=True, primary_key=True)
@ -110,7 +120,9 @@ class Users(PgSQLModel):
@staticmethod
def auth(email, password, status=1):
if Users.select().where(
Users.email == email, Users.password == Users.hash_password(password), Users.status == status
Users.email == email,
Users.password == Users.hash_password(password),
Users.status == status
).count() == 0:
return False
return True
@ -121,7 +133,11 @@ class Users(PgSQLModel):
@staticmethod
def get_by_id(user_id):
return Users.select().where(Users.id == user_id).get()
return Users.select().where(Users.id == user_id).first()
@staticmethod
def get_by_email(email):
return Users.select().where(Users.email == email).first()
class UsersRecoveryCodes(PgSQLModel):

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -114,14 +114,15 @@ def registration():
user_id = ControllerUsers().get_id_by_email(email)
ControllerUsersDetails(user_id).details_create()
ControllerBilling().create(user_id, g.settings['bonus'])
ControllerBilling().create(user_id, g.settings.get('bonus', 0))
ControllerAPI().set(user_id=user_id, secret=user_id, acl='', status=0)
# ControllerU
# send mail message with recovery code
message = u"""
Е-почта: %s
Пароль: %s
""" % (request.form['email'], request.form['password'])
""" % (request.form.get('email'), request.form.get('password'))
subject = u'GoCloud.ru: Успешная регистрация'
lead = u"""
Поздравляем с успешной регистрацией.
@ -130,10 +131,12 @@ def registration():
Для входа в личный кабинет воспользуйтесь
<a href="https://gocloud.ru/account/login">страницей авторизации</a>.
"""
email = ControllerMessagesEmail()
email.send(title=subject, to=request.form['email'], lead=lead, message=message, callout=callout)
try:
email = ControllerMessagesEmail()
email.send(title=subject, to=request.form['email'], lead=lead, message=message, callout=callout)
except Exception as e:
# TODO: write message
pass
# redirect to login page
flash(u'Учетная запись успешно зарегистрирована.', 'success')
return redirect(url_for('account.login'))

View file

@ -1,57 +0,0 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
1 0 obj
<< /F1 2 0 R /F2 3 0 R /F3 4 0 R >>
endobj
2 0 obj
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
endobj
3 0 obj
<< /BaseFont /ZapfDingbats /Encoding /ZapfDingbatsEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
endobj
4 0 obj
<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >>
endobj
5 0 obj
<< /Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
/Type /Page >>
endobj
6 0 obj
<< /Outlines 10 0 R /PageMode /UseNone /Pages 8 0 R /Type /Catalog >>
endobj
7 0 obj
<< /Author (anonymous) /CreationDate (D:20161016043545-03'00') /Creator (ReportLab PDF Library - www.reportlab.com) /Keywords () /ModDate (D:20161016043545-03'00') /Producer (ReportLab PDF Library - www.reportlab.com)
/Subject (unspecified) /Title (untitled) /Trapped /False >>
endobj
8 0 obj
<< /Count 1 /Kids [ 5 0 R ] /Type /Pages >>
endobj
9 0 obj
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 735 >>
stream
GasJPgN)"%&;KYAnN1Qb2mh$p3r4rMVN;4S9M8:0o\'IG#dN4>AdE<^Be<hY@c;s8q=i@@FtJURd5T$fOTF5_E-4g)1.YG2KeFQoJ8+#&rd#f(=\4%YGebF-,<qiQl'Vh@an4dMP`TG>kQ+u/`Zr=3r2g^b-k.lUmI^LCk74u@CK)JQ#\18LWr5OS(-LdAS.D-;?`\=9'WQ4E)2H=GYuQ&Q:IVk]/;C:l,6%eP0-JM^Zo*hl9jJh13EmLqHkqBD>Fd\H2g+u@9V&>(\Lr(ZQ1*g4Q1/*N?/uhi?OS@-82hCT,T;,0dWmd#HA`%oY>R#_4KDHdZUmAd&#4H%(AsJ1C4KcP[FDkE/;>k(8W,b"d_+GdLB1<BW$RY%:1"40!+_$"V>@5R;R"gGohPUPnc7,oXVAuZmRX:!mDlIV+%o0q+r6%6G_c\l:h4ZQ0a*n,/G=3b/IIli@D4@7"^rsL,8!"o'B7*N6I_.<76^h:?OIIk_oRsp`I=[aXl(P.[]4MPhpSe,6WhKr^h$#^6Q'EJ(Cf#9[g^o.O'pVP1<l/9g\KR2>FGms]h6\mnF++Nc#`c[5M^T0T1R[^UYMBR$o3nG#;>SA&Z)_+*ZRTi=A]Th,)r\&#?IWGdY82-R'\?<!NN$c<6bWHVXIL#)60S&<+<jAYeJb)DkoSHQqsV@:.N>%O@5Fq@s],dSsSJJS`X-9'K]D3V<LYJ[Au3rWiC:C+3rf(rW.VMNog~>endstream
endobj
10 0 obj
<< /Count 0 /Type /Outlines >>
endobj
xref
0 11
0000000000 65535 f
0000000075 00000 n
0000000129 00000 n
0000000239 00000 n
0000000357 00000 n
0000000472 00000 n
0000000669 00000 n
0000000757 00000 n
0000001057 00000 n
0000001119 00000 n
0000001949 00000 n
trailer
<< /ID
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
[(F\377\262C\004ZI\203\233\321\244^\250\251\025\300) (F\377\262C\004ZI\203\233\321\244^\250\251\025\300)]
/Info 7 0 R /Root 6 0 R /Size 11 >>
startxref
1999
%%EOF

View file

@ -162,5 +162,6 @@ setup(
'wsgiref==0.1.2',
'sshpubkeys==1.0.6',
'dateutils',
'redis',
]
)

Binary file not shown.