Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add admin controller and a command to make admins #527

Merged
merged 1 commit into from
Mar 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fact-bounty-flask/api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def register_commands(app):
app.cli.add_command(commands.clean)
app.cli.add_command(commands.urls)
app.cli.add_command(commands.deploy)
app.cli.add_command(commands.create_admin)


def register_shellcontext(app):
Expand Down
61 changes: 61 additions & 0 deletions fact-bounty-flask/api/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from flask.cli import with_appcontext
from flask_migrate import upgrade
from werkzeug.exceptions import MethodNotAllowed, NotFound
from .user import model
import getpass
import re


COV = None
Expand All @@ -18,6 +21,25 @@
COV.start()


"""
function for
for validating an Email
with regex to check email string
"""


def check(email):
"""
pass the regualar expression
and the string in search() method
"""
regex = r"^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$"
if re.search(regex, email):
return True
else:
return False


@click.command()
@click.option(
"--coverage/--no-coverage",
Expand Down Expand Up @@ -168,3 +190,42 @@ def deploy():
migrate database to latest revision
"""
upgrade()


@click.command(name="create_admin")
@with_appcontext
def create_admin():
"""
create an admin user
"""
admin_username = input("Enter the admin username: ")
passwords_not_same = False

while not passwords_not_same:
admin_password = getpass.getpass(prompt="Enter the admin password: ")
admin_password2 = getpass.getpass(prompt="Renter the admin password: ")
valid = bool(admin_password == admin_password2)
if valid:
break
else:
print("Passwords dont match renter the passwords")
admin_role = "admin"
valid = False
while not valid:
admin_email = input("Enter the admin email: ")
valid = check(admin_email)
if valid:
break
else:
pass
try:
user = model.User(
name=admin_username,
email=admin_email,
password=admin_password,
role=admin_role,
)
user.save()

except Exception as e:
return {"Error occured": str(e)}
52 changes: 30 additions & 22 deletions fact-bounty-flask/api/stories/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,49 @@
from elasticsearch.helpers import scan
from .model import Vote, Comment
from flasgger import swag_from
from ..user import model


class AllStories(MethodView):
"""
Retrieve stories
Retrieve stories only for admin
:return: JSON object with all stories and HTTP status code 200.
"""

@jwt_required
@swag_from("../../docs/stories/get_all.yml")
def get(self):
user_id = get_jwt_identity()
user = model.User.find_by_user_id(user_id)

es_index = current_app.config["ES_INDEX"]
es = current_app.elasticsearch
if user.role == "admin":
es_index = current_app.config["ES_INDEX"]
es = current_app.elasticsearch

doc = {
"sort": [{"date": {"order": "desc"}}],
"query": {"match_all": {}},
}
stories = {}
try:
for story in scan(es, doc, index=es_index, doc_type="story"):
PID = story["_id"]
source = story["_source"]
stories[PID] = source
except Exception as e:
# An error occured, so return a string message containing error
response = {"message": str(e)}
return make_response(jsonify(response)), 500
doc = {
"sort": [{"date": {"order": "desc"}}],
"query": {"match_all": {}},
}
stories = {}
try:
for story in scan(es, doc, index=es_index, doc_type="story"):
PID = story["_id"]
source = story["_source"]
stories[PID] = source
except Exception as e:
# An error occured, so return a string message containing error
response = {"message": str(e)}
return make_response(jsonify(response)), 500

response = {
"message": "Stories successfully fetched",
"stories": stories,
}
return make_response(jsonify(response)), 200
response = {
"message": "Stories successfully fetched",
"stories": stories,
}
return make_response(jsonify(response)), 200
else:
response = {"message": "only for admins"}
return make_response(jsonify(response)), 400


class GetRange(MethodView):
Expand Down
19 changes: 18 additions & 1 deletion fact-bounty-flask/api/user/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ class User(Model):
date = Column(db.DateTime, default=datetime.now())
votes = db.relationship("Vote", backref=db.backref("user"))
type = Column(db.String(50), default="remote")
role = Column(db.String(10), default="user")

def __init__(self, name, email, password, _type="remote"):
def __init__(self, name, email, password, role="user", _type="remote"):
"""
Initializes the user instance
"""
Expand All @@ -35,6 +36,7 @@ def __init__(self, name, email, password, _type="remote"):
if password:
self.password = User.generate_password_hash(password)
self.type = _type
self.role = role

def __repr__(self):
"""
Expand All @@ -55,12 +57,27 @@ def to_json(self):
def find_by_email(cls, email):
return cls.query.filter_by(email=email).first()

@classmethod
def find_by_user_id(cls, _id):
return cls.query.filter_by(id=_id).first()

@classmethod
def find_by_verification_token(cls, verification_token):
return cls.query.filter_by(
verification_token=verification_token
).first()

@classmethod
def verify_admin(cls, email):
"""
Verify admin role
"""
try:
query = cls.query.filter_by(email=email, role="admin").first()
return query
except Exception as err:
print("Error: ", err)

@staticmethod
def generate_token():
"""
Expand Down
30 changes: 30 additions & 0 deletions fact-bounty-flask/migrations/versions/8be924798f34_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""empty message

Revision ID: 8be924798f34
Revises: 28906f0ff936
Create Date: 2020-03-09 13:46:18.009784

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "8be924798f34"
down_revision = "28906f0ff936"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"user", sa.Column("role", sa.String(length=10), nullable=True)
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("user", "role")
# ### end Alembic commands ###