# Application Flow



## Ring Creation

1. Ring owner downloads Ringspace binary
2. Creates a new ring for `https://goodring.com`
  - `ringspace create -u https://goodring.com`
  - `ringspace serve`
  - A new ring manifest is created and hosted at `https://goodring.com/.well-known/webring.json`

## Joining a Ring

1. Ring owner creates an invite code for new member `https://newmember.com`
  - `ringspace invite create --url https://newmember.com`
    - `InviteCommands::Create` **DONE**
    - `create_invite()` **DONE**
2. Ring owner sends invite code to member through secure means
3. Member uses invite code to join their website to a ring.
  - `ringspace site join-ring -u https://goodring.com -i <invite_code>`
    - `SiteCommands::JoinRing` **DONE**
  - The member's public key is sent to the ring with the invite code at `https://goodring.com/api/invite/redeem` **DONE**
    - If accepted, the member is added to the ring's database in the `members` table.
    - `enroll_member()` **DONE**
  - **DONE** The ring responds with its public keys for signing and encryption, which are used to save the ring information.
  - The site adds the ring to `joined_rings`.
  - `create_joined_ring()` **DONE**
4. Ring member generates new manifest and places in in `.well-known/webring.json`.
  - `ringspace site manifest > /path/to/webroot/.well-known/webring.json`

## Voting

1. Ring member `https://newmember.com` creates a vote for good standing `https://othermember.com`
  - `ringspace site vote -v -s 10 https://othermember.com -d "Great Content"` **DONE**
    - The vote is added to the `site_votes` table locally **DONE**
2. The member regenerates their manifest.
  - `ringspace site manifest > /path/to/webroot/.well-known/webring.json` **DONE**
    - **DONE** For each vote subject, the most recent vote is added to the site manifest under the subject's URL as a key
    - The votes are encrypted using the ring's public encryption key (`encrypt_vote`) **DONE**
3. **DONE** The server, on a scheduled interval, fetches all manifests and updates votes.

## User Validation

1. A user visits `https://newmember.com`. The Webring widget advertises that it's a member of the Good Ring.
2. **TODO** The user clicks the `validate` button on the widget.
3. The widget's JavaScript reaches out to `https://goodring.com/api/validate` via POST request with the site's current manifest.
4. **TODO** The server performs the following checks:
  1. The `Origin` of the validation request matches the member validation being requested
  2. **DONE** The submitted manifest's public key is compared to the one on record. If it's a match, the signature is verified.
  3. **DONE** If the signature verifies, the server loads the most recent vote from all known votes from member sites and evaluates average standing.
  4. The standing score, voting sites, and validation result are returned to the requester.
  5. The widget provides information about the returned result.


## Leaving a Ring

1. A ring member wishes to separate from a ring. They use the CLI to run `ringspace unenroll -r https://goodring.com`.
  - **DONE** An API request is sent to `https://goodring.com/api/member/unenroll` containing: the URL, public key, and signature of that payload.
  - **DONE** If the signature is verified by the ring server, the ring will be unenrolled (deleted) from the ring. Specifically, it is deleted from the `members` table and the `memberships` table is update to represent the change.

## Rotate Keys

1. **DONE** A ring member wishes to rotate their keys. The member runs `site rotate-keys`
  - A new signing keypair is generated.
  - The new keys are sent to joined rings. The JSON payload with the new keys is signed with the current signing key for authentication.
2. **DONE** The rings update the keys on their end if the signature verifies.
  - If the rotation request is successful for all joined rings, the local key is updated to the new key. If there's a problem with any joined ring rotation, the keys for successful rotations are rotated back to prevent lockout.
3. **DONE** The local database entry is updated.
