diff --git a/fact-bounty-flask/api/app.py b/fact-bounty-flask/api/app.py index f8c360d2..8f503e47 100644 --- a/fact-bounty-flask/api/app.py +++ b/fact-bounty-flask/api/app.py @@ -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): diff --git a/fact-bounty-flask/api/commands.py b/fact-bounty-flask/api/commands.py index e99267ad..4897553a 100644 --- a/fact-bounty-flask/api/commands.py +++ b/fact-bounty-flask/api/commands.py @@ -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 @@ -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", @@ -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)} diff --git a/fact-bounty-flask/api/stories/controller.py b/fact-bounty-flask/api/stories/controller.py index 5855eb05..05bbd45f 100644 --- a/fact-bounty-flask/api/stories/controller.py +++ b/fact-bounty-flask/api/stories/controller.py @@ -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): diff --git a/fact-bounty-flask/api/user/model.py b/fact-bounty-flask/api/user/model.py index dcc80b00..a19b35f5 100644 --- a/fact-bounty-flask/api/user/model.py +++ b/fact-bounty-flask/api/user/model.py @@ -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 """ @@ -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): """ @@ -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 print(query) + except Exception as err: + print("Error: ", err) + @staticmethod def generate_token(): """ diff --git a/fact-bounty-flask/migrations/versions/8be924798f34_.py b/fact-bounty-flask/migrations/versions/8be924798f34_.py new file mode 100644 index 00000000..b2e4ffa5 --- /dev/null +++ b/fact-bounty-flask/migrations/versions/8be924798f34_.py @@ -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 ###