summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README53
-rw-r--r--demo.yaml17
-rwxr-xr-xrun.sh16
-rw-r--r--testconfig.json5
-rw-r--r--tomjon.yaml18
-rw-r--r--verence.yaml18
-rw-r--r--yarns/000.yarn42
7 files changed, 27 insertions, 142 deletions
diff --git a/README b/README
index df234ba..2a9155b 100644
--- a/README
+++ b/README
@@ -1,28 +1,9 @@
Effireg - the Effi membership register
=============================================================================
-This will become a web-based membership register for the Effi
-association.
-
-The current goal is an MVP version that can be demoed at the fall
-general meeting. There will be a running demo site, with some dummy
-data. It will support the following use cases:
-
-* Admin can create new members via the API.
-* Admin can list all members via the API.
-* Admin can search for members (name, email) via the API.
-* Admin can view a member's information via the API.
-* Admin can update a member's information via the API.
-* Admin can set a member's password via the API.
-* A member can access the API, but only sees their own information.
-* A member can log in via a web browser and see their own information.
-
-Authentication will be handled by Qvisqve. Any member can
-authenticate. Data will be stored in Muck, including authentication
-information. A custom facade application will provide the API. A
-custom application will provide a server-side rendered front-end.
-
-The front-end application uses the facade API to access all data.
+This will become a web-based membership register for the Effi -
+Electronic Frontier Finland association (<https://effi.org/>). It may
+some day be useful for others as well.
Architecture and documentation
-----------------------------------------------------------------------------
@@ -35,11 +16,11 @@ Facade API
The facade will have an API like this:
-* `GET /search` &mdash; search for members
-* `GET /memb` &mdash; get specific member
* `POST /memb` &mdash; add a member
+* `GET /memb` &mdash; get specific member
* `PUT /memb` &mdash; update a member
* `DELETE /memb` &mdash; remove a member
+* `GET /search` &mdash; search for members
All operations require an access token from Qvisqve. The Muck header
conventions are used for metadata.
@@ -53,33 +34,27 @@ A member's information looks like:
"hometown": "London"
}
-(This is known to be insufficient. It's for demo purposes only, for
-now. It will change.)
-
+Actually, currently any JSON object will work, but this will change
+eventually.
Resource types in Muck
=============================================================================
-* `subject` represents a human being whose information is stored in
- the system
- * contains nothing that isn't needed for authentication
-* `password` stores the subject's password
- * references `subject` resource id
- * contains a salted, scrypt'd password
* `member` contains all non-authentication information about an Effi
member
* references `subject` resource id
* contains full name, membership number, home town, email address
+There may later be authentication related resources in Muck, but for
+now, Qvisqve stores them a different way.
+
Authentication
-----------------------------------------------------------------------------
-For the demo I will create users manually. Later on, Qvisqve will need
-to store subjects in Muck.
-
-For the demo, Muck will be changed to allow a user with the super scope
-be able to set the owner of a resource. This is necessary so that admin
-can create resources for members, but members can see them.
+For the demo I will create subjects in Qvisqve manually. Later on,
+Effireg will create subjects itself, and provide a way to generate a
+per-subject unique URL which authenticates the subject without a
+password. Effectively a password reset link.
Legalese
diff --git a/demo.yaml b/demo.yaml
deleted file mode 100644
index c338c94..0000000
--- a/demo.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-demo:
- label: |
- Demo at fall GM
- depends:
- - seeownweb
-
-seeownweb:
- label: |
- Members can see their
- own info via web browser
- depends:
- - demosite_exists
-
-demosite_exists:
- label: |
- A demo site exists
- status: finished
diff --git a/run.sh b/run.sh
deleted file mode 100755
index 592cf7f..0000000
--- a/run.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-tokenurl=https://effi-reg.vm.liw.fi
-apiurl=https://effi-reg.vm.liw.fi
-
-#tokenurl="https://muck-muck.vm.liw.fi"
-#apiurl="http://localhost:8080"
-
-./effitool \
- --log effitool.log \
- -i admin -s hunter2 \
- -u "$apiurl" \
- -t "$tokenurl" \
- "$@"
diff --git a/testconfig.json b/testconfig.json
deleted file mode 100644
index 5ed6916..0000000
--- a/testconfig.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "muck-url": "https://muck-muck.vm.liw.fi",
- "log": "effiapi.log",
- "pid": "effiapi.pid"
-}
diff --git a/tomjon.yaml b/tomjon.yaml
deleted file mode 100644
index 0576c81..0000000
--- a/tomjon.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-fullname: Tomjon of Lancre
-birthday: '1969-09-01'
-address: |
- Palace
- Lancre
- Ramtom mountains
- Discworld
-home_council: Lancre
-residence_country: Lancre
-primary_email_address: tomjon@example.com
-primary_email_address_tested_dates: ['2018-11-24']
-secondary_email_address: tomjon@genua.example.com
-secondary_email_address_tested_dates: ['2018-01-01']
-membership_type: 'annual'
-membership_years: [2017, 2018]
-membership_years_paid: [2017, 2018]
-membership_years_not_paid: [2019]
-mailing_lists: ['effi-aktivistit@listat.effi.org']
diff --git a/verence.yaml b/verence.yaml
deleted file mode 100644
index 1901da6..0000000
--- a/verence.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-fullname: Verence of Lancre
-birthday: '1969-09-01'
-address: |
- Palace
- Lancre
- Ramtom mountains
- Discworld
-home_council: Lancre
-residence_country: Lancre
-primary_email_address: verence@example.com
-primary_email_address_tested_dates: ['2018-11-24']
-secondary_email_address: verence@genua.example.com
-secondary_email_address_tested_dates: ['2018-01-01']
-membership_type: 'annual'
-membership_years: [2017, 2018]
-membership_years_paid: [2017, 2018]
-membership_years_not_paid: [2019]
-mailing_lists: ['effi-aktivistit@listat.effi.org']
diff --git a/yarns/000.yarn b/yarns/000.yarn
index 4e6719c..d9f16f5 100644
--- a/yarns/000.yarn
+++ b/yarns/000.yarn
@@ -4,6 +4,7 @@ author: Lars Wirzenius
...
[yarn]: https://liw.fi/cmdtest/
+[Effireg]: https://effireg.liw.fi/
# Introduction
@@ -12,6 +13,9 @@ scenario tests. It is meant to be understandable to Effi sysadmins,
and those writing applications using the API, as well as be an
executable test suite for the API.
+Effiapi is part of [Effireg][], a privacy-aware register of members
+for associations.
+
The API is a simple RESTful HTTP API using JSON. This means that:
* each API call is an HTTP request, with a response
@@ -31,12 +35,13 @@ Examples will be provided.
# Test scenarios
-## Manage memberships
-
-This section shows the API calls to manage a memberhip.
+## Manage memberships - happy path
- SCENARIO Manage memberships
+This section shows the API calls to manage a memberhip. The test
+scaffolding starts an effiapi instance, and defines an API client for
+the administrator, which has all the access.
+ SCENARIO Manage a membership
GIVEN An effiapi instance
First make sure the register is empty.
@@ -50,7 +55,7 @@ First make sure the register is empty.
THEN HTTP status is 200
AND body matches { "resources": [] }
-Create a member.
+Create a member. Check in various ways that it exists.
WHEN admin requests POST /memb with body { "fullname": "James Bond" }
THEN HTTP status is 201
@@ -83,7 +88,7 @@ Update the member.
AND body matches { "fullname": "Alfred Pennyworth" }
AND header Muck-Revision is ${REV2}
-Delete the member.
+Delete the member. Check in various ways that it no longer exists.
WHEN admin requests DELETE /memb with id ${ID}
THEN HTTP status is 200
@@ -104,14 +109,10 @@ Done.
FINALLY Effiapi is terminated
-TODO:
-
-* search
-* members can see their own data, and can't see each others'
-* member follows authn link emailed to them
-
# Appendix: Yarn scenario step implementations
+Most of the interesting code is in the `lib.py` module.
+
## Start and stop effiapi
IMPLEMENTS GIVEN An effiapi instance
@@ -134,9 +135,6 @@ TODO:
rid = get_expanded_match()
rev = get_expanded_match()
body = get_json_match()
- print('rid', repr(rid))
- print('rev', repr(rev))
- print('body', repr(body))
headers = {
'Muck-Id': rid,
'Muck-Revision': rev,
@@ -145,9 +143,7 @@ TODO:
IMPLEMENTS WHEN admin requests GET /memb with header (\S+): (\S+)
header = get_next_match()
- print('header', repr(header))
value = get_expanded_match()
- print('value', repr(value))
headers = {
header: value,
}
@@ -155,7 +151,6 @@ TODO:
IMPLEMENTS WHEN admin requests GET /search with (.+)
body = get_expanded_json_match()
- print('body', repr(body))
headers = {
'Content-Type': 'application/json',
}
@@ -163,7 +158,6 @@ TODO:
IMPLEMENTS WHEN admin requests DELETE /memb with id (\S+)
rid = get_expanded_match()
- print('rid', repr(rid))
headers = {
'Muck-id': rid,
}
@@ -174,31 +168,21 @@ TODO:
IMPLEMENTS THEN HTTP status is (\d+)
expected = int(get_next_match())
actual = effiapi.get_status_code()
- print 'actual:', repr(actual)
- print 'expecting:', repr(expected)
assertEqual(effiapi.get_status_code(), expected)
IMPLEMENTS THEN remember header (\S+) as (.+)
header = get_next_match()
varname = get_next_match()
value = effiapi.get_header(header)
- print 'header:', repr(header)
- print 'value:', repr(value)
- print 'varname:', repr(varname)
save_for_expansion(varname, value)
IMPLEMENTS THEN header (\S+) is (.+)
header = get_next_match()
expected = get_expanded_match()
actual = effiapi.get_header(header)
- print 'header:', repr(header)
- print 'expected:', repr(expected)
- print 'actual:', repr(actual)
assertEqual(actual, expected)
IMPLEMENTS THEN body matches (.+)
expected = get_expanded_json_match()
actual = effiapi.get_json_body()
- print 'expected:', expected
- print 'actual: ', actual
assertEqual(actual, expected)