Skip to content

Commit

Permalink
Merge pull request #1212 from ScilifelabDataCentre/multiple_motds
Browse files Browse the repository at this point in the history
Adds ls and deactivate subcommands to dds motd and displaying of multiple active motds
  • Loading branch information
i-oden authored Aug 4, 2022
2 parents 8dfdfd9 + d2f5dda commit b400349
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 32 deletions.
4 changes: 2 additions & 2 deletions dds_web/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ def create_app(testing=False, database_uri=None):
@app.before_request
def prepare():
"""Populate flask globals for template rendering"""
from dds_web.utils import get_latest_motd
from dds_web.utils import get_active_motds

# Get message of the day
flask.g.motd = get_latest_motd()
flask.g.motd = get_active_motds()

flask.g.current_user = None
flask.g.current_user_emails = None
Expand Down
48 changes: 44 additions & 4 deletions dds_web/api/superadmin_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,57 @@ def post(self):
raise ddserr.DDSArgumentError(message="No MOTD specified.")

flask.current_app.logger.debug(motd)
new_motd = models.MOTD(message=motd, date_created=curr_date)
new_motd = models.MOTD(message=motd)
db.session.add(new_motd)
db.session.commit()

return {"message": "The MOTD was successfully added to the database."}

@handle_db_error
def get(self):
"""Get the latest MOTD from database."""
motd = utils.get_latest_motd()
return {"message": motd}
"""Return list of all active MOTDs to super admin."""
active_motds = models.MOTD.query.filter_by(active=True).all()
if not active_motds:
return {"message": "There are no active MOTDs."}

motd_info = [
{
"MOTD ID": m.id,
"Message": m.message,
"Created": m.date_created.strftime("%Y-%m-%d %H:%M"),
}
for m in active_motds
]

return {"motds": motd_info, "keys": ["MOTD ID", "Message", "Created"]}

@auth.login_required(role=["Super Admin"])
@logging_bind_request
@json_required
@handle_db_error
def put(self):
"""Deactivate MOTDs."""
# Get motd id
json_input = flask.request.json
motd_id = json_input.get("motd_id")
if not motd_id:
raise ddserr.DDSArgumentError(message="No MOTD for deactivation specified.")

# Get motd row from db
motd_to_deactivate = models.MOTD.query.filter_by(id=motd_id).first()
if not motd_to_deactivate:
raise ddserr.DDSArgumentError(
message=f"MOTD with id {motd_id} does not exist in the database"
)

# Check if motd is active
if not motd_to_deactivate.active:
raise ddserr.DDSArgumentError(message=f"MOTD with id {motd_id} is not active.")

motd_to_deactivate.active = False
db.session.commit()

return {"message": "The MOTD was successfully deactivated in the database."}


class FindUser(flask_restful.Resource):
Expand Down
3 changes: 2 additions & 1 deletion dds_web/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,8 @@ class MOTD(db.Model):
# Columns
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
message = db.Column(db.Text, nullable=False, default=None)
date_created = db.Column(db.DateTime(), nullable=False, default=None)
date_created = db.Column(db.DateTime(), nullable=False, default=dds_web.utils.current_time())
active = db.Column(db.Boolean, nullable=False, default=True)


class Usage(db.Model):
Expand Down
4 changes: 3 additions & 1 deletion dds_web/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
{% if g.motd %}
<div class="alert alert-warning" role="alert">
<h3>Important Information</h3>
<pre>{{ g.motd }}</pre>
{% for message in g.motd %}
<p>{{ message.date_created.strftime("%Y-%m-%d %H:%M") }} - {{ message.message }}</p>
{% endfor %}
</div>
{% endif %}
</div>
Expand Down
8 changes: 5 additions & 3 deletions dds_web/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,9 @@ def bucket_is_valid(bucket_name):
return valid, message


def get_latest_motd():
def get_active_motds():
"""Return latest MOTD."""
motd_object = models.MOTD.query.order_by(models.MOTD.date_created.desc()).first()
return motd_object.message if motd_object else ""
motds_active = (
models.MOTD.query.filter_by(active=True).order_by(models.MOTD.date_created.desc()).all()
)
return motds_active or None
26 changes: 26 additions & 0 deletions migrations/versions/908382be548a_add_column_active_to_motd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""add_column_active_to_motd
Revision ID: 908382be548a
Revises: cd1903e5f2b0
Create Date: 2022-06-13 12:34:34.981373
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = "908382be548a"
down_revision = "cd1903e5f2b0"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("motd", sa.Column("active", sa.Boolean(), nullable=False))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("motd", "active")
# ### end Alembic commands ###
49 changes: 46 additions & 3 deletions tests/test_superadmin_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def test_get_motd_no_message(client):
"""Get latest MOTD from database."""
response = client.get(tests.DDSEndpoint.MOTD, headers={"X-CLI-Version": "0.0.0"})
assert response.status_code == http.HTTPStatus.OK
assert not response.json.get("message")
assert "There are no active MOTDs." in response.json.get("message")


def test_get_motd(client):
Expand All @@ -140,7 +140,8 @@ def test_get_motd(client):
# Get first message
response1 = client.get(tests.DDSEndpoint.MOTD, headers={"X-CLI-Version": "0.0.0"})
assert response1.status_code == http.HTTPStatus.OK
assert "test" in response1.json.get("message")
assert isinstance(response1.json.get("motds"), list)
assert "test" in response1.json.get("motds")[0]["Message"]

time.sleep(5)

Expand All @@ -154,7 +155,49 @@ def test_get_motd(client):
# Check that new message is displayed
response3 = client.get(tests.DDSEndpoint.MOTD, headers={"X-CLI-Version": "0.0.0"})
assert response3.status_code == http.HTTPStatus.OK
assert "something else" in response3.json.get("message")
assert "something else" in response3.json.get("motds")[1]["Message"]

# Deactivate message
response4 = client.put(tests.DDSEndpoint.MOTD, headers=token, json={"motd_id": 1})
assert response4.status_code == http.HTTPStatus.OK
assert "The MOTD was successfully deactivated in the database." in response4.json.get("message")

# Deactivate message that is not active
response5 = client.put(tests.DDSEndpoint.MOTD, headers=token, json={"motd_id": 1})
assert response5.status_code == http.HTTPStatus.BAD_REQUEST
assert "MOTD with id 1 is not active." in response5.json.get("message")


def test_deactivate_motd_no_json(client):
token = get_token(username=users["Super Admin"], client=client)
response = client.put(tests.DDSEndpoint.MOTD, headers=token)
assert response.status_code == http.HTTPStatus.BAD_REQUEST
assert "Required data missing from request!" in response.json.get("message")


def test_deactivate_motd_no_motd_id(client):
token = get_token(username=users["Super Admin"], client=client)
response = client.put(tests.DDSEndpoint.MOTD, headers=token, json={"test": "test"})
assert response.status_code == http.HTTPStatus.BAD_REQUEST
assert "No MOTD for deactivation specified." in response.json.get("message")


def test_deactivate_motd_no_such_motd(client):
token = get_token(username=users["Super Admin"], client=client)
response = client.put(tests.DDSEndpoint.MOTD, headers=token, json={"motd_id": 8})
assert response.status_code == http.HTTPStatus.BAD_REQUEST
assert "MOTD with id 8 does not exist in the database" in response.json.get("message")


def test_deactivate_motd_not_superadmin(client):
"""Deactivate a message of the day, using everything but Super Admin access."""
no_access_users = users.copy()
no_access_users.pop("Super Admin")

for u in no_access_users:
token = get_token(username=users[u], client=client)
response = client.put(tests.DDSEndpoint.MOTD, headers=token)
assert response.status_code == http.HTTPStatus.FORBIDDEN


# FindUser
Expand Down
18 changes: 0 additions & 18 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,21 +774,3 @@ def test_bucket_is_valid_ok():
valid, message = utils.bucket_is_valid(bucket_name="something-.")
assert valid
assert message == ""


# get_latest_motd


def test_get_latest_motd_no_motd(client: FlaskClient):
motd = utils.get_latest_motd()
assert not motd


def test_get_latest_motd(client: FlaskClient):
new_message: str = "test message"
new_motd = models.MOTD(message=new_message, date_created=utils.current_time())
db.session.add(new_motd)
db.session.commit()

motd = utils.get_latest_motd()
assert motd == new_message

0 comments on commit b400349

Please sign in to comment.