# Path: marvinbot/models.py
# class User(mongoengine.Document):
#     id = mongoengine.LongField(primary_key=True)
#     first_name = mongoengine.StringField()
#     last_name = mongoengine.StringField()
#     username = mongoengine.StringField()
#     password = mongoengine.StringField()
#     active = mongoengine.BooleanField(default=True)
# 
#     # TODO: Implement proper groups
#     role = EnumField(RoleType, default=DEFAULT_ROLE)
#     banned = mongoengine.BooleanField(default=False)
#     auth_token = mongoengine.StringField()
# 
#     def is_admin(self):
#         # TODO: Actually check groups
#         return self.role in POWER_USERS
# 
#     @classmethod
#     def by_id(cls, user_id):
#         try:
#             return cls.objects.get(id=user_id)
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def by_username(cls, username):
#         try:
#             return cls.objects.get(username=username)
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def is_user_admin(cls, user_data):
#         u = cls.by_id(user_data.id)
#         if not u:
#             return False
#         return u.is_admin()
# 
#     @classmethod
#     def from_telegram(cls, user_data, save=False):
#         prev = cls.by_id(user_data.id)
#         if prev:
#             return prev, False
#         user = cls(id=user_data.id, first_name=user_data.first_name, last_name=user_data.last_name,
#                    username=user_data.username)
#         if save:
#             user.save()
#         return user, True
# 
#     def check_password(self, password):
#         """Check if the password is correct"""
#         if not self.password:
#             return False
#         return self.active and verify_password(password, self.password)
# 
#     def change_password(self, new_pass):
#         """Encrypts and sets the user's password"""
#         self.password = hash_password(new_pass)
# 
#     def is_authenticated(self):
#         return True
# 
#     def is_active(self):
#         return self.active
# 
#     def is_anonymous(self):
#         return False
# 
#     def get_id(self):
#         return self.username
# 
#     def __str__(self):
#         return "{id}: {username}".format(id=self.id, username=self.username or '<NoUserName>')
# 
# Path: marvinbot/forms.py
# class LoginForm(FlaskForm):
#     username = StringField('username', validators=[DataRequired()])
#     passwd = PasswordField('passwd', validators=[])
# 
# Path: marvinbot/utils/net.py
# def is_safe_url(request, target):
#     ref_url = urlparse(request.host_url)
#     test_url = urlparse(urljoin(request.host_url, target))
#     return test_url.scheme in ('http', 'https') and \
#            ref_url.netloc == test_url.netloc


import logging
from flask import (
    request, session, g, redirect, url_for, abort, render_template,
    flash, current_app, Blueprint
)
from flask_login import login_user, logout_user, current_user, login_required
from marvinbot.models import User
from marvinbot.forms import LoginForm
from marvinbot.utils.net import is_safe_url

log = logging.getLogger(__name__)
marvinbot = Blueprint('marvinbot', __name__, template_folder='templates')


@marvinbot.route('/')
@login_required
def home():
    return render_template('index.html')


@marvinbot.route('/login', methods=["GET", "POST"])
def login():
    form = LoginForm()

    if form.validate_on_submit():
        user = User.by_username(form.username.data)

        if user and user.check_password(form.passwd.data):
            login_user(user, remember=True)

            flash('Successful login')

            next_url = request.args.get('next')
            # is_safe_url should check if the url is safe for redirects.
            # See http://flask.pocoo.org/snippets/62/ for an example.
            if not is_safe_url(request, next_url):
                return abort(400)
            return redirect(next_url or url_for(".home"))


# Path: marvinbot/models.py
# class User(mongoengine.Document):
#     id = mongoengine.LongField(primary_key=True)
#     first_name = mongoengine.StringField()
#     last_name = mongoengine.StringField()
#     username = mongoengine.StringField()
#     password = mongoengine.StringField()
#     active = mongoengine.BooleanField(default=True)
# 
#     # TODO: Implement proper groups
#     role = EnumField(RoleType, default=DEFAULT_ROLE)
#     banned = mongoengine.BooleanField(default=False)
#     auth_token = mongoengine.StringField()
# 
#     def is_admin(self):
#         # TODO: Actually check groups
#         return self.role in POWER_USERS
# 
#     @classmethod
#     def by_id(cls, user_id):
#         try:
#             return cls.objects.get(id=user_id)
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def by_username(cls, username):
#         try:
#             return cls.objects.get(username=username)
#         except cls.DoesNotExist:
#             return None
# 
#     @classmethod
#     def is_user_admin(cls, user_data):
#         u = cls.by_id(user_data.id)
#         if not u:
#             return False
#         return u.is_admin()
# 
#     @classmethod
#     def from_telegram(cls, user_data, save=False):
#         prev = cls.by_id(user_data.id)
#         if prev:
#             return prev, False
#         user = cls(id=user_data.id, first_name=user_data.first_name, last_name=user_data.last_name,
#                    username=user_data.username)
#         if save:
#             user.save()
#         return user, True
# 
#     def check_password(self, password):
#         """Check if the password is correct"""
#         if not self.password:
#             return False
#         return self.active and verify_password(password, self.password)
# 
#     def change_password(self, new_pass):
#         """Encrypts and sets the user's password"""
#         self.password = hash_password(new_pass)
# 
#     def is_authenticated(self):
#         return True
# 
#     def is_active(self):
#         return self.active
# 
#     def is_anonymous(self):
#         return False
# 
#     def get_id(self):
#         return self.username
# 
#     def __str__(self):
#         return "{id}: {username}".format(id=self.id, username=self.username or '<NoUserName>')
# 
# Path: marvinbot/forms.py
# class LoginForm(FlaskForm):
#     username = StringField('username', validators=[DataRequired()])
#     passwd = PasswordField('passwd', validators=[])
# 
# Path: marvinbot/utils/net.py
# def is_safe_url(request, target):
#     ref_url = urlparse(request.host_url)
#     test_url = urlparse(urljoin(request.host_url, target))
#     return test_url.scheme in ('http', 'https') and \
#            ref_url.netloc == test_url.netloc


# Path: marvinbot/views.py
import logging
from flask import (
    request, session, g, redirect, url_for, abort, render_template,
    flash, current_app, Blueprint
)
from flask_login import login_user, logout_user, current_user, login_required
from marvinbot.models import User
from marvinbot.forms import LoginForm
from marvinbot.utils.net import is_safe_url


log = logging.getLogger(__name__)
marvinbot = Blueprint('marvinbot', __name__, template_folder='templates')


@marvinbot.route('/')
@login_required
def home():
    return render_template('index.html')


@marvinbot.route('/login', methods=["GET", "POST"])
def login():
    form = LoginForm()

    if form.validate_on_submit():
        user = User.by_username(form.username.data)

        if user and user.check_password(form.passwd.data):
            login_user(user, remember=True)

            flash('Successful login')

            next_url = request.args.get('next')
            # is_safe_url should check if the url is safe for redirects.
            # See http://flask.pocoo.org/snippets/62/ for an example.
            if not is_safe_url(request, next_url):
                return abort(400)
            return redirect(next_url or url_for(".home"))


    return render_template("login.html", form=form)