Skip to content

Commit

Permalink
add version tag in UI + more input validation (#84) + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fmigneault committed Jul 30, 2020
1 parent c4e4641 commit e5c46d9
Show file tree
Hide file tree
Showing 18 changed files with 92 additions and 24 deletions.
4 changes: 3 additions & 1 deletion HISTORY.rst → CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. :changelog:
History
Changes
=======

`Unreleased <https://github.com/Ouranosinc/Magpie/tree/master>`_ (latest)
Expand All @@ -26,13 +26,15 @@ Features / Changes
(fixes `#204 <https://github.com/Ouranosinc/Magpie/issues/204>`_).
* Add disabled checkboxes for UI rendering of non-editable items
(relates to `#164 <https://github.com/Ouranosinc/Magpie/issues/164>`_).
* Add version tag at bottom of UI pages.
* Configuration parameters ``MAGPIE_SECRET``, ``MAGPIE_ADMIN_USER`` and ``MAGPIE_ADMIN_PASSWORD`` now require explicit
definitions (either by environment variable or INI settings) to avoid using defaults for security purposes.

Bug Fixes
~~~~~~~~~~~~~~~~~~~~~
* Fix invalid API documentation of request body for ``POST /users/{user_name}/groups``.
* Fix `#164 <https://github.com/Ouranosinc/Magpie/issues/164>`_ (forbid *special* users and groups update and delete).
* Fix `#84 <https://github.com/Ouranosinc/Magpie/issues/84>`_ with additional input validation.
* Fix minor HTML issues in mako templates.

`1.11.0 <https://github.com/Ouranosinc/Magpie/tree/1.11.0>`_ (2020-06-19)
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Before you submit a pull request, check that it meets these guidelines:
1. The pull request should include tests.
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in `history`_ (under relevant category of section `Unreleased`).
feature to the list in `changes`_ (under relevant category of section `Unreleased`).
3. The tests should work for the specified version of Python for this project.


Expand All @@ -93,6 +93,6 @@ To run a subset of tests::

.. References for this page
.. _new issue: https://github.com/Ouranosinc/Magpie/issues/new
.. _history: HISTORY.rst
.. _changes: CHANGES.rst
.. _installation: docs/installation.rst
.. _utilities: docs/utilities.rst
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ RUN chmod 0644 $CRON_DIR/magpie-cron

# install dependencies
COPY magpie/__init__.py magpie/__meta__.py $MAGPIE_DIR/magpie/
COPY requirements* setup.py README.rst HISTORY.rst $MAGPIE_DIR/
COPY requirements* setup.py README.rst CHANGES.rst $MAGPIE_DIR/
RUN apk update \
&& apk add \
bash \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.adapter
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ LABEL Vendor="CRIM"

ENV MAGPIE_DIR=/opt/local/src/magpie
COPY magpie/__init__.py magpie/__meta__.py $MAGPIE_DIR/magpie/
COPY requirements* setup.py README.rst HISTORY.rst $MAGPIE_DIR/
COPY requirements* setup.py README.rst CHANGES.rst $MAGPIE_DIR/

# install dependencies used by Magpie
RUN apk update \
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ Configuration and Usage
Change History
==============

Addressed features, changes and bug fixes per version tag are available in `history`_.
Addressed features, changes and bug fixes per version tag are available in `changes`_.

.. _history: HISTORY.rst
.. _changes: CHANGES.rst

Docker Images
=============
Expand Down
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. include:: ../CHANGES.rst
1 change: 0 additions & 1 deletion docs/history.rst

This file was deleted.

2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Package Information
performance
contributing
authors
history
changes
security


Expand Down
4 changes: 3 additions & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ If you want the full setup for development (including dependencies for test exec
make install-dev


You can run the Magpie container with a docker-compose.yml for a local setup (see docker-compose.yml.example)
You can run the Magpie container with a ``docker-compose.yml`` for a local setup (see `docker-compose.yml.example`_)

.. _`docker-compose.yml.example`: https://github.com/Ouranosinc/Magpie/tree/master/docker-compose.yml.example
6 changes: 6 additions & 0 deletions magpie/api/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from sys import exc_info
from typing import TYPE_CHECKING

import colander
import six
from pyramid.httpexceptions import (
HTTPBadRequest,
Expand Down Expand Up @@ -34,6 +35,11 @@
RAISE_RECURSIVE_SAFEGUARD_MAX = 5
RAISE_RECURSIVE_SAFEGUARD_COUNT = 0

# utility parameter validation regexes for 'matches' argument
PARAM_REGEX = r"^[A-Za-z0-9]+(?:[\s_\-\.][A-Za-z0-9]+)*$" # request parameters
EMAIL_REGEX = colander.EMAIL_RE
URL_REGEX = colander.URL_REGEX


def verify_param( # noqa: E126
# --- verification values ---
Expand Down
2 changes: 1 addition & 1 deletion magpie/api/management/service/service_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def _add_service_magpie_and_phoenix(svc, svc_push, db):

ax.verify_param(service_type, is_in=True, param_compare=SERVICE_TYPE_DICT.keys(), param_name="service_type",
http_error=HTTPBadRequest, msg_on_fail=s.Services_POST_BadRequestResponseSchema.description)
ax.verify_param(service_url, matches=True, param_compare=colander.URL_REGEX, param_name="service_url",
ax.verify_param(service_url, matches=True, param_compare=ax.URL_REGEX, param_name="service_url",
http_error=HTTPBadRequest, msg_on_fail=s.Services_POST_Params_BadRequestResponseSchema.description)
ax.verify_param(service_name, not_empty=True, not_none=True, param_compare="service_name",
http_error=HTTPBadRequest, msg_on_fail=s.Services_POST_Params_BadRequestResponseSchema.description)
Expand Down
10 changes: 6 additions & 4 deletions magpie/api/management/user/user_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import TYPE_CHECKING

import colander
from pyramid.httpexceptions import (
HTTPBadRequest,
HTTPConflict,
Expand Down Expand Up @@ -52,11 +51,14 @@ def create_user(user_name, password, email, group_name, db_session):

def _get_group(grp_name):
# type: (Str) -> models.Group
ax.verify_param(grp_name, not_none=True, not_empty=True, matches=True,
param_compare=ax.PARAM_REGEX, param_name="group_name",
http_error=HTTPBadRequest, msg_on_fail=s.UserGroup_Check_BadRequestResponseSchema.description)
grp = ax.evaluate_call(lambda: GroupService.by_group_name(grp_name, db_session=db_session),
http_error=HTTPForbidden,
msg_on_fail=s.UserGroup_GET_ForbiddenResponseSchema.description)
ax.verify_param(grp, not_none=True, http_error=HTTPBadRequest,
msg_on_fail=s.UserGroup_Check_BadRequestResponseSchema.description)
ax.verify_param(grp, not_none=True, http_error=HTTPNotFound, param_name="group_name",
msg_on_fail=s.UserGroup_Check_NotFoundResponseSchema.description)
return grp

# Check that group already exists
Expand Down Expand Up @@ -345,7 +347,7 @@ def check_user_info(user_name, email, password, group_name):
msg_on_fail=s.Users_CheckInfo_ReservedKeyword_BadRequestResponseSchema.description)
ax.verify_param(email, not_none=True, not_empty=True, http_error=HTTPBadRequest,
param_name="email", msg_on_fail=s.Users_CheckInfo_Email_BadRequestResponseSchema.description)
ax.verify_param(email, matches=True, param_compare=colander.EMAIL_RE, http_error=HTTPBadRequest,
ax.verify_param(email, matches=True, param_compare=ax.EMAIL_REGEX, http_error=HTTPBadRequest,
param_name="email", msg_on_fail=s.Users_CheckInfo_Email_BadRequestResponseSchema.description)
ax.verify_param(password, not_none=True, not_empty=True, http_error=HTTPBadRequest,
param_name="password",
Expand Down
8 changes: 7 additions & 1 deletion magpie/api/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ class User_DELETE_ForbiddenResponseSchema(colander.MappingSchema):


class UserGroup_Check_BadRequestResponseSchema(colander.MappingSchema):
description = "Group for new user doesn't exist."
description = "Invalid group name to associate to user."
header = HeaderResponseSchema()
body = BaseResponseBodySchema(code=HTTPBadRequest.code, description=description)

Expand All @@ -1536,6 +1536,12 @@ class UserGroup_GET_ForbiddenResponseSchema(colander.MappingSchema):
body = BaseResponseBodySchema(code=HTTPForbidden.code, description=description)


class UserGroup_Check_NotFoundResponseSchema(colander.MappingSchema):
description = "Group for new user doesn't exist."
header = HeaderResponseSchema()
body = BaseResponseBodySchema(code=HTTPBadRequest.code, description=description)


class UserGroup_Check_ForbiddenResponseSchema(colander.MappingSchema):
description = "Failed to add user-group to db."
header = HeaderResponseSchema()
Expand Down
20 changes: 20 additions & 0 deletions magpie/ui/home/static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,26 @@ body {
margin: 5em;
}

.version-box {
position: absolute;
right: 0;
}

.version-box>div{
font-size: 75%;
display: inline-block;
position: relative;
bottom: 1em;
right: 1em;
}

.version-title {
color: gray;
}

.version-tag {
}

.img-button {
padding: 0.7em;
margin: 1em 0 1em;
Expand Down
8 changes: 4 additions & 4 deletions magpie/ui/home/templates/template.mako
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@
<div class="content">
${self.body()}
</div>
<div class="version-box">
<div class="version-title">Magpie Version: </div>
<div class="label label-info version-tag">${MAGPIE_VERSION}</div>
</div>

</body>
</html>

<script type="text/javascript">
<%block name="script"/>
</script>
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ replace = APP_VERSION ?= {new_version}
search = __version__ = "{current_version}"
replace = __version__ = "{new_version}"

[bumpversion:file:HISTORY.rst]
[bumpversion:file:CHANGES.rst]
search =
`Unreleased <https://github.com/Ouranosinc/Magpie/tree/master>`_ (latest)
------------------------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
with open("README.rst") as readme_file:
README = readme_file.read()

with open("HISTORY.rst") as history_file:
HISTORY = history_file.read().replace(".. :changelog:", "")
with open("CHANGES.rst") as changes_file:
CHANGES = changes_file.read().replace(".. :changelog:", "")


def _split_requirement(requirement, version=False, python=False):
Expand Down Expand Up @@ -154,7 +154,7 @@ def _extra_requirements(base_requirements, other_requirements):
name=__meta__.__package__,
version=__meta__.__version__,
description=__meta__.__description__,
long_description=README + "\n\n" + HISTORY,
long_description=README + "\n\n" + CHANGES,
author=__meta__.__author__,
maintainer=__meta__.__maintainer__,
maintainer_email=__meta__.__email__,
Expand Down
30 changes: 30 additions & 0 deletions tests/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,36 @@ def test_PostUsers(self):
users = utils.TestSetup.get_RegisteredUsersList(self)
utils.check_val_is_in(self.test_user_name, users)

@runner.MAGPIE_TEST_USERS
def test_PostUsers_InvalidParameters(self):
utils.warn_version("validate user creation inputs", "2.0.0", skip=True)
data = {
"user_name": self.test_user_name,
"email": "{}@mail.com".format(self.test_user_name),
"password": self.test_user_name,
"group_name": self.test_user_group,
}
for code, variant in [
(400, {"user_name": ""}),
(400, {"user_name": " "}),
(400, {"user_name": "abc???def"}),
(400, {"user_name": "abc/def"}),
(400, {"user_name": "A" * 1024}),
(400, {"email": ""}),
(400, {"email": " "}),
(400, {"email": "abc???def"}),
(400, {"email": "abc/def"}),
(400, {"email": "abc-def @ gmail dot com"}),
(400, {"password": ""}),
(400, {"password": " "}),
(400, {"group_name": "!ABC!"}),
(404, {"group_name": ""}),
]:
var_data = deepcopy(data).update(variant)
resp = utils.test_request(self, "POST", "/users", json=var_data, expect_errors=True,
headers=self.json_headers, cookies=self.cookies)
utils.check_response_basic_info(resp, code, expected_method="POST")

@runner.MAGPIE_TEST_USERS
def test_PostUsers_AutoMemberships(self):
new_test_group = "test-group-{}".format(self._testMethodName) # noqa
Expand Down

0 comments on commit e5c46d9

Please sign in to comment.