Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
959fe41
Merge pull request #1 from bird-house/master
agstephens Oct 14, 2020
d2978ea
Merge pull request #6 from bird-house/master
antony-wilson Nov 5, 2020
70146f5
Add openlayers map selection for bbox
antony-wilson Nov 17, 2020
c3f3807
Add a range slider widget
antony-wilson Nov 19, 2020
3e5d62a
remove ceda.css checked in by mistake
antony-wilson Nov 19, 2020
7e761b9
Add a date range slider widget
antony-wilson Nov 20, 2020
be157bf
Merge pull request #7 from cedadev/bbox
antony-wilson Nov 20, 2020
430eeeb
Merge pull request #8 from cedadev/range-slider
antony-wilson Nov 20, 2020
698ffb2
Update the range slider widgets
antony-wilson Nov 20, 2020
42fb19c
CEDA branding
antony-wilson Nov 20, 2020
61f7f34
update ceda style
antony-wilson Nov 20, 2020
b35f48a
Update bounding box widget to select projection based on the initial
antony-wilson Nov 23, 2020
bb99256
add ceda_security module
antony-wilson Nov 23, 2020
0e684ee
update ceda security module
antony-wilson Nov 24, 2020
eecd47e
update styling
antony-wilson Nov 24, 2020
420769e
change favicon to ceda favicon
antony-wilson Nov 25, 2020
d3de096
Move admin login to separate page
antony-wilson Nov 25, 2020
36d8a7e
Update ceda security to do a db lookup
antony-wilson Nov 25, 2020
283acbf
The page count on the monitor page is not an int
antony-wilson Nov 25, 2020
e1eefae
Merge pull request #12 from cedadev/monitor_page_page_count
antony-wilson Nov 25, 2020
74d299c
update text on home page
antony-wilson Nov 25, 2020
39266b1
add chameleon dependency as we are having trouble with the latest
antony-wilson Nov 25, 2020
cb09d26
Patched requirements.txt - as was not working in ansible
agstephens Nov 25, 2020
c5f1658
Merge pull request #13 from cedadev/requirements-patch
agstephens Nov 25, 2020
29d6cee
Add hidden crs input field to the bbox form
antony-wilson Nov 26, 2020
2a6763a
remove `Please wait ...` banner
antony-wilson Nov 26, 2020
4cb6b3c
remove async tick box
antony-wilson Nov 27, 2020
2f08dff
move hard coded crs from template to execute
antony-wilson Nov 27, 2020
3c679d5
Use a SelectWidget with multiple = true when selecting multiple strings
antony-wilson Nov 27, 2020
5d5c98c
add vocab validator
antony-wilson Nov 27, 2020
72f2703
remove missing_thumb.png images
antony-wilson Nov 27, 2020
8315670
fix VocabValidator when looking at strings
antony-wilson Nov 30, 2020
09eaae2
remove birdhouse and further reading links from help drop down
antony-wilson Nov 30, 2020
72e8fff
add a second delay when a job is submitted before going to the monitor
antony-wilson Nov 30, 2020
2d5310c
get ceda query from custom.cfg
antony-wilson Dec 1, 2020
add7f7f
Add `ssl-certificate` and `ssl-certificate-key` parameters for use in
antony-wilson Dec 1, 2020
780c97f
Updated SSL-related settings
agstephens Dec 1, 2020
58c15ae
Added "group" to: buildout.cfg
agstephens Dec 2, 2020
4fa53e1
Updated: buildout.cfg
agstephens Dec 2, 2020
cd84ea9
add buildout defaults for `group` and `ssl-client-certificate`
antony-wilson Dec 4, 2020
7d65b19
Add "help beacon" script to default template
antony-wilson Dec 4, 2020
c26c43c
Updated mongodb lookup on "title" as well as "identifier"
agstephens Dec 4, 2020
9c86fbc
add Google Tag Manager to the default template
antony-wilson Dec 8, 2020
ecb722e
Update owslib version to 0.21
antony-wilson Dec 15, 2020
381df69
File Upload Widget
antony-wilson Dec 16, 2020
add6e8d
Add more comments to the file_upload_store
antony-wilson Dec 18, 2020
73f1174
Changes have been made for where user management is handled outside of
antony-wilson Jan 6, 2021
6fd480e
The file upload widget now returns a URL rather than a directory path
antony-wilson Jan 7, 2021
202e461
Updated "User Documentation" link in Help
agstephens Mar 12, 2021
4a9259a
Merge pull request #24 from cedadev/help-link-update
agstephens Mar 12, 2021
dd5d3d5
Get phoenix to read metalink document to provide direct download links
antony-wilson May 26, 2021
b040367
Renamed metlink to metalink
agstephens May 27, 2021
47853af
Renamed metlink to metalink
agstephens May 27, 2021
c992a49
Updated requirements.txt
agstephens Jun 7, 2021
88eded8
Updated environment.yml
agstephens Jun 7, 2021
c85a17c
Updated environment.yml and requirements.txt to avoid duplication
agstephens Jun 8, 2021
3aae395
Added conda spec-list for quick install.
agstephens Jun 8, 2021
1b36cee
Updated ceda security
agstephens Jun 15, 2021
e6a5790
Merge branch 'master' into fixes-from-server
agstephens Jun 15, 2021
6bca970
Updated home.pt
agstephens Jun 17, 2021
8f0b163
Updated home.pt
agstephens Jun 17, 2021
f57a833
Updated interactions with: CEDA Security
agstephens Nov 8, 2021
a58ce44
Added fix for showing non-file outputs alongside file outputs.
agstephens Apr 19, 2022
4f79406
Updated: ceda_security.py - to include "restricted_by_user_id" dict.
agstephens Jul 26, 2022
f1dc4ba
Merge branch 'master' of https://github.com/cedadev/pyramid-phoenix
agstephens Jul 26, 2022
a64af38
add script to parse stats
agstephens Oct 2, 2023
d5abb8e
add status_location to output
agstephens Oct 24, 2023
9f9dc33
add script for getting usage stats
agstephens Apr 5, 2024
a522324
write output in JSON and text format
agstephens Apr 5, 2024
85d8dc3
make output file stem configurable in log parser
agstephens Apr 5, 2024
1fa560e
add option to filter job report by maximum job age
agstephens Apr 5, 2024
33584b4
add cron wrapper for get-wps-stats
agstephens Apr 16, 2024
a205957
Updated controls to add "Toggle longitude window" button
agstephens Apr 17, 2024
29088af
Updated to allow toggling between -180,180 and 0,360
agstephens Apr 17, 2024
b6da374
Updated after test
agstephens Apr 17, 2024
3c28883
Updated with 2 nudge buttons
agstephens Apr 23, 2024
a63dcbb
Updated validators.
agstephens Jul 2, 2024
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
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Changes
*******

* Use released owslib=0.21

0.11.0 (2020-02-04)
===================

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ init: custom.cfg downloads

bootstrap-buildout.py:
@echo "Update buildout bootstrap-buildout.py ..."
@test -f boostrap-buildout.py || curl https://bootstrap.pypa.io/bootstrap-buildout.py --insecure --silent --output bootstrap-buildout.py
@test -f bootstrap-buildout.py || curl https://bootstrap.pypa.io/bootstrap-buildout.py --insecure --silent --output bootstrap-buildout.py

## Build targets

Expand Down
14 changes: 12 additions & 2 deletions buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ versions = versions
birdhousebuilder.recipe.celery = 0.2.0
birdhousebuilder.recipe.conda = 0.4.0
birdhousebuilder.recipe.mongodb = 0.4.0
birdhousebuilder.recipe.nginx = 0.4.0
birdhousebuilder.recipe.nginx = 0.4.2
birdhousebuilder.recipe.supervisor = 0.4.0
collective.recipe.template = 2.1
zc.recipe.deployment = 1.3.0
Expand All @@ -38,15 +38,19 @@ zc.recipe.egg = 2.0.7
[settings]
prefix = ${environment:HOME}/birdhouse
user = ${environment:USER}
group =
etc-user = ${:user}
hostname = localhost
http-port = 8081
https-port = 8443
ssl-client-certificate = cert.pem
ssl-certificate-key = cert.pem
project = Phoenix
version = 0.10.dev
phoenix-debug = false
phoenix-secret = f4e044d933767d6d0e022d1020508db3
phoenix-password = qwerty
local-user-management = true
log-level = WARNING
mongodb-host = localhost
mongodb-port = 27027
Expand All @@ -73,6 +77,8 @@ keycloak-client-secret =
twitcher-url = http://localhost:8000
twitcher-client-id =
twitcher-client-secret =
file-upload-storage-dir = /tmp
file-upload-max-size-mb = 250

[deployment]
recipe = zc.recipe.deployment
Expand Down Expand Up @@ -151,12 +157,16 @@ user = ${deployment:user}
etc-user = ${deployment:etc-user}
input = ${buildout:directory}/templates/nginx.conf
socket = ${phoenix_config:socket}
hostname = ${settings:hostname}
hostname = ${settings:hostname}
http-port = ${settings:http-port}
https-port = ${settings:https-port}
client_max_body_size = ${phoenix_config:max_file_size}m
storage_path = ${phoenix_config:storage_path}
group = ${settings:group}
twitcher_url = ${settings:twitcher-url}
ssl-client-certificate = ${settings:ssl-client-certificate}
ssl-certificate-key = ${settings:ssl-certificate-key}
ssl-trusted-certificate = ${settings:ssl-trusted-certificate}

[celery]
recipe = birdhousebuilder.recipe.celery
Expand Down
22 changes: 3 additions & 19 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,30 +28,14 @@ dependencies:
- pyyaml
- pygments
- pytz
- owslib=0.19
- owslib>=0.21.0
- transaction
- genshi=0.7
- pyjwt
# celery
- celery=3.1
- kombu=3.0
# mongodb
- pymongo=3
- pymongo>=3.3.0
- mongodb>=3.4
- pip:
- pyramid
- pyramid-beaker
- Beaker
- pyramid-deform
- deform
- pyramid-chameleon
- pyramid-mako
- pyramid-layout
- pyramid-celery==3.0.0
- pyramid-storage
- pyramid-rpc
- colander
- Authomatic==0.1.0.post1
- python-openid2==3.0
- WebHelpers2
- WebHelpers2_grid

5 changes: 5 additions & 0 deletions phoenix/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
__version__ = '0.11.0'

import os, ssl
if (not os.environ.get('PYTHONHTTPSVERIFY', '') and
getattr(ssl, '_create_unverified_context', None)):
ssl._create_default_https_context = ssl._create_unverified_context


def main(global_config, **settings):
"""
Expand Down
1 change: 1 addition & 0 deletions phoenix/account/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

def includeme(config):
config.add_route('sign_in', '/account/login')
config.add_route('sign_in_admin', '/admin')
config.add_route('account_logout', '/account/logout')
config.add_route('account_auth', '/account/auth/{provider}')
config.add_route('account_register', '/account/register')
Expand Down
2 changes: 1 addition & 1 deletion phoenix/account/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def login_success(self, login_id, provider=None, token=None):
user['provider'] = provider
user['last_login'] = datetime.now()
self.collection.update({'login_id': login_id}, user)
self.session.flash("Hello <strong>{0}</strong>. Welcome to Phoenix.".format(escape(login_id)), queue='info')
self.session.flash("Hello <strong>{0}</strong>. Welcome to CEDA WPS.".format(escape(login_id)), queue='info')
if provider != 'keycloak':
# generate_access_token(self.request.registry, userid=user['identifier'])
pass
Expand Down
14 changes: 11 additions & 3 deletions phoenix/account/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@
class LocalSchema(deform.schema.CSRFSchema):
password = colander.SchemaNode(
colander.String(),
title='Admin password',
description='If you have not configured your password yet then it is likely to be "qwerty"',
title='password',
validator=colander.Length(min=6),
widget=deform.widget.PasswordWidget())


class LocalAccount(Account):
def schema(self):
return deform.schema.CSRFSchema()

@view_config(route_name='sign_in', renderer='phoenix:account/templates/account/sign_in.pt')
def sign_in(self):
return self.login()


class AdminAccount(Account):

def schema(self):
return LocalSchema().bind(request=self.request)
Expand All @@ -28,6 +36,6 @@ def _handle_appstruct(self, appstruct):
return self.login_success(login_id="admin", provider='local')
return self.login_failure()

@view_config(route_name='sign_in', renderer='phoenix:account/templates/account/sign_in.pt')
@view_config(route_name='sign_in_admin', renderer='phoenix:account/templates/account/sign_in_admin.pt')
def sign_in(self):
return self.login()
4 changes: 0 additions & 4 deletions phoenix/account/templates/account/sign_in.pt
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@
class="btn btn-warning btn-lg"><icon class="fa fa-globe"></icon> Sign in with CEDA</a>
<br/><br/>
</div>
<span class="text-muted">OR</span>
<br/><br/>
<tal:form replace="structure form">The form will render here</tal:form>
<!-- a href="${request.route_path('account_register')}" class="btn btn-link">Register for an account</a -->
</div>
</div><!-- panel -->
</div>
Expand Down
23 changes: 23 additions & 0 deletions phoenix/account/templates/account/sign_in_admin.pt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<metal:block use-macro="main_template">
<div metal:fill-slot="javascript">
<script src="${request.static_path('phoenix:static/phoenix/js/authomatic.js')}"></script>
</div>

<div metal:fill-slot="content">
<div class="container">
<br/>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-success text-center">
<div class="panel-body">
<h2>Sign In</h2>
<tal:form replace="structure form">The form will render here</tal:form>
<!-- a href="${request.route_path('account_register')}" class="btn btn-link">Register for an account</a -->
</div>
</div><!-- panel -->
</div>
</div><!-- row -->
</div><!-- container -->
</div>

</metal:block>
17 changes: 16 additions & 1 deletion phoenix/catalog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from mako.template import Template
import re
import uuid
from os.path import join, dirname
from collections import namedtuple
Expand Down Expand Up @@ -87,7 +88,21 @@ def __init__(self, collection):
self.collection = collection

def get_record_by_id(self, identifier):
return doc2record(self.collection.find_one({'identifier': identifier}))
"""
Gets database record by identifier or title.

If the identifier does not match, then a case-insensitive
match is made on the title (replacing "_" with " "). This
enables _deterministic_ URLs in which the WPS can be identified
by a meaningful string as well as the standard long identifier.
"""
doc = self.collection.find_one({'identifier': identifier})

if not doc:
title_regex = re.compile('^' + re.escape(identifier.replace('_', ' ')) + '$', re.IGNORECASE)
doc = self.collection.find_one({'title': title_regex})

return doc2record(doc)

def delete_record(self, identifier):
self.collection.delete_one({'identifier': identifier})
Expand Down
83 changes: 83 additions & 0 deletions phoenix/ceda_security.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import json

from sqlalchemy import create_engine

import logging
LOGGER = logging.getLogger("PHOENIX")


CEDA_ROLE_MAP_CONFIG = "/usr/local/birdhouse/etc/phoenix/ceda_process_role_map.json"


def check_ceda_permissions(request, user, processid):
"""
Check if the user has permission to access the process.
Return a boolean:
- True: allow access
- False: deny access
"""
role_mappings = _get_process_role_mappings()
restricted_procs = role_mappings["restricted_by_role"]

if processid in role_mappings.get("open", []):
# If open, everyone can access
return True

if user is None or user.get("login_id") in role_mappings["suspended_users"]:
# the user is not logged or is suspended so we return False
return False

if processid in role_mappings.get("restricted_to_ceda_users", []):
# the process is available to all CEDA users
return True

if user.get("login_id") in role_mappings["restricted_by_user_id"].get(processid, []):
# the process is available to this specific user
return True

users_roles = _get_user_roles(request, user.get("login_id"))

for role in users_roles:
if role in restricted_procs.get(processid, []):
return True

return False


def _get_process_role_mappings():
"""
Load the role mappings from the config file.
"""
try:
with open(CEDA_ROLE_MAP_CONFIG) as reader:
return json.load(reader)
except Exception:
# If cannot read it, set defaults
return {"restricted_by_role": {}, "restricted_to_ceda_users": [],
"open": [], "suspended_users": [], "restricted_by_user_id": {}}


def _get_user_roles(request, user_id):
"""
Call out to the DB to get the users rolls.
"""
connection_credentials = request.registry.settings.get("ceda.db.creds")
engine = create_engine(connection_credentials)

with engine.connect() as conn:
query = request.registry.settings.get("ceda.db.query")
query = query.replace("{user_id}", user_id)
roles = set(_get_response(conn, query))
roles = sorted(
[r for r in roles if not r.startswith("gws_") and not r.startswith("vm_")]
)

return roles


def _get_response(conn, query, get_one=False):
rs = conn.execute(query)
results = [item[0] for item in rs]
if get_one:
results = results[0]
return results
Loading