Commit Graph

47 Commits

Author SHA1 Message Date
Fintan Halpenny af99d6f47a
radicle: set identity head on init
Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-27 10:13:04 +01:00
Fintan Halpenny a32101ab75
radicle: canoncial refs/rad/id
Introduce a canonical reference for refs/rad/id to aid in discovering
information about a repository without knowing a peer -- e.g. if a
peer wants to clone a new repository it needs to find out which peers
are delegates for that project, but does not know what their NIDs are
up front.

The approach mirrors the canonical `head` for a repository and
introduces useful constructors for `Doc`/`DocAt`.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-27 10:13:03 +01:00
Fintan Halpenny d476d35887
radicle: populate MockRepository
The MockStorage holds an inventory of repositories and their
identities but when asking for a MockRepository, none of this
information is transferred.

Add `id` and `doc` fields to MockRepository for defining some of its
functionality.

In addition, add a generator for a nonempty MockStorage to use in
tests that will expect the storage to be populated.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-03-08 11:29:33 +00:00
Alexis Sellier 0a93fa833e
cli: Simplify & improve CLI output
Improvements to the CLI output as well as converging towards
`termion` as a backend.

The crates we were using for prompting and spinners were based on
a terminal backend called `console`, which is not really used
anywhere else. There were also limitations in terms of the output
of these crates.

Therefore, we switched to the `inquire` crate for prompting, using
the `termion` backend, which is very standard.

Additionally, we simplify the terminal output to use symbols:

! for Warning
✓ for Success
✗ for Error

... Instead of a mix of words and symbols.

We also include a modified version of the `yansi` crate which plays
well with our table formatting functions by automatically truncating
and padding output in a unicode-aware way.
2023-02-27 17:10:52 +01:00
Fintan Halpenny 5ea8505000
radicle: custom CanonicalFormatter
The olpc-json crate's CanonicalFormatter does not escape certain
control characters, including new lines. This means that when a COB
gets serialized that includes new lines, those new lines are
serialized verbatim. Upon deserialization `serde_json` -- and any
other JSON deserializer -- will fail due to the encounter of these
control characters.

This behaviour was prevented in radicle-link with the definition of
its own CanoncialFormatter that encodes the control characters
correctly.

Inline this definition of the formatter, under MIT license, to ensure
the correct and remove oplc-cjson.

The behaviour is checked using a multiline test in the issue COB.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-24 11:59:36 +01:00
Sebastian Martinez b04451a1bd
Use `Did` in a bunch more places
Instead of showing just public keys we need to show the fully qualified
spec for a NID which is prefixed by `did🔑` While we want to maintain
`Author` and `ActorId` for internal use.

Signed-off-by: Sebastian Martinez <me@sebastinez.dev>
2023-02-16 18:01:42 +01:00
Fintan Halpenny efe5ff6ddd
radicle: Did improvements
Add conversion from Did to PublicKey through a From implementation.

Add FromStr implementation.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-16 17:07:14 +01:00
Alexis Sellier 950fae209d
Make `ReadStorage` more usable
Previously, we were not able to access a `ReadRepository` instance
through `ReadStorage`. With this change, we are able to.
2023-02-15 22:08:20 +01:00
Fintan Halpenny 88fc4f1782
radicle: ensure stable commits for Docs
`Doc::commit` used `git2::Signature::now` when committing the document
to the repository. This results in the commits always changing and not
allowing us to test outputs of our CLI commands that would wish to
output the SHA.

Make `Doc::commit` reproducible in debug mode using `debug_assertions`
and checking the `RAD_COMMIT_TIME` environment variable.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-13 18:02:20 +01:00
Fintan Halpenny 540c56cac6
radicle: sign blob hash instead of content
The signatures for Radicle identities were using the documents
content.

It is standard to use the hash of the content instead, since signing
and verification is faster on a smaller set of data.

Use the resulting Git blob's object id, i.e. `git hash-object`, as the
signing and verifying payload.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-13 13:30:44 +01:00
Fintan Halpenny 3f48c2c516
Rust 1.67
Rust 1.67 was announced[0]. Update the necessary files for running
1.67 and fix the clippy suggestions for string interpolation.

[0]: https://blog.rust-lang.org/2023/01/26/Rust-1.67.0.html

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2023-02-04 19:30:29 +01:00
Alexis Sellier 1f06f5340f
Make `Id` to string conversion more explicit
Two types of conversion: `canonical`, which is just the base58 encoding,
and `urn` which is like canonical, but includes `rad:`.
2023-01-24 13:49:03 +01:00
Fintan Halpenny aa05f676f7
cli: add delegate cli
Adds a `rad delegate` CLI command.

The command consists of three subcommands:
* `add` -- add a new delegate to the set of delegates of a project
* `remove` -- remove an existing delegate from the set of delegates of a
  project
* `list` -- list the delegates of a project

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-12-27 12:25:24 +01:00
Fintan Halpenny d7170ff9e7
radicle: ensure unique signatures when parsing trailers
To ensure that signatures are unique for verifying an identity a
HashMap is used in place of a Vec of tuples.

This prevents any double counting for quorum checks.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-12-27 12:23:39 +01:00
Fintan Halpenny adaed6a3ac
radicle: validated construction of Project
The `validate` method of `Project` was unused, which is problematic if
the attributes are supposed to be validated based on some
constraints. The issue is that `Project` provided public construction
of its fields with enforcing validation.

This change makes `Project`'s attributes private and introduces a
smart constructor `new` which is fallible if any of the constraints
are not met. The error type was changed to be a vector of errors since
all of these errors can be collected for better error reporting.

Deserialization also provided a way of constructing a `Project`
without ensuring any of the constraints were checked. To prevent this
a hand-rolled `Deserialize` is provided that goes through
`Project::new`.

To access the fields of `Project`, accessor functions are added and
all call sites are updated to use them.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-12-27 12:23:39 +01:00
Alexis Sellier bdbf111163
Refactor identity verification
Introduces a new `DocAt` type.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-12 15:01:47 +01:00
Alexis Sellier edafe055b4
Verify identity root commit signatures
In RIP-2, we specify that identity document root commits must include
the signature of all founding delegates.

This commit adds the required signatures during document creation
and verifies them on load.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-12 15:01:42 +01:00
Alexis Sellier c183f80a22
Cleanup some of the git error variants
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 22:06:21 +01:00
Alexis Sellier d309f593b1
Move doc initialization to storage
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 22:06:21 +01:00
Alexis Sellier b37fef9f22
Re-organize identity types and modules
The new hierarchy should be much more correct, and cleaner:

* `identity` (`Identity`)
* `identity::did` (`Did`)
* `identity::doc` (`Doc`, `Payload`)
  * `identity::doc::id` (`Id`)
* `identity::project` (`Project`)

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 22:06:20 +01:00
Alexis Sellier 8735719ecc
radicle: Remove unused error variants
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 22:05:42 +01:00
Alexis Sellier 98c1566109
Make `Doc` type payload generic 2022-12-09 22:05:38 +01:00
Alexis Sellier b7c1f091fa
Fix issue with colliding doc files
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-09 14:37:36 +01:00
Alexis Sellier 66d76d7ab2
radicle: Use `defaultBranch` for payload key
This was changed by mistake from the previous format used in radicle
link. We restore all keys to camel-case.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-07 18:01:47 +01:00
Alexis Sellier 207d2133f9
Remove delegate names from identity doc
We are working on other mechanisms to help identify keys, and this
is just redundant.

Also update some of the CLI examples to create a canonical example
for documentation.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-07 12:16:00 +01:00
Alexis Sellier f9c81ab382
Replace `quickcheck` with `qcheck`
The latter is a fork of the former, which adds const generics
and a bunch of other quality of life improvements that aren't
in the original crate due to it being unmaintained.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-04 20:40:54 +01:00
Alexis Sellier 3a2584b544
Add `rad:` prefix to project ids
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-01 12:06:39 +01:00
Alexis Sellier dd7052926a
cob: Remove `author` from `Entry`
It was no longer used.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-12-01 12:05:44 +01:00
xphoniex 80401f89ae
Add `rad-inspect` command
Signed-off-by: xphoniex <dj.2dixx@gmail.com>
2022-11-14 12:23:24 +01:00
Fintan Halpenny cb2d83daae
radicle: wire up radicle-cob
To wire up radicle-cob, it is necessary to implement the traits for
the following types:
* `Repository`: `change::Storage`, `object::Storage`, and `Store`
* `project::Identity`: `identity::Identity`

For `Repository`, the `change::Storage` implementation is trivial, as
it uses the underlying `git2::Repository` implementation. Then
`object::Storage` simply defines the required references names and
does lookups or updates.

The aforementioned reference naming scheme is:

  refs/namespaces/<ns>/refs/cobs/<typename>/<object_id>

For `project::Identity`, the `identity::Identity` implementation is
straight-forward.

To finalise the work, a simplified API is exposed as `radicle::cob`
where the `create`, `update`, `get`, and `list` functions are
redefined in terms of `radicle` specific types.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-11-08 18:13:54 +00:00
Alexis Sellier 577b632056
Use `Signer::try_sign` in interactive contexts
In interactive (user) contexts, use `try_sign` instead of `sign`.

We also revisit the `Profile` by adding a `signer` method that can
fail, eg. if we couldn't connect to ssh-agent.

Finally, we replace `UnsafeSigner` with `MemorySigner`, which makes
use of `ssh::Keystore`.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-11-03 13:06:00 +01:00
Alexis Sellier a79ef67b2a
Add `Signer::try_sign` method and cleanup usage
To support ssh-agent, add a signing method that can fail.
Also cleanup usage so that we always accept signer references.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-11-03 10:12:22 +01:00
Alexis Sellier 16b22d9178
Move `radicle/id` and `radicle/signature`
We move the identity branch out of `heads/` and to the old location:

  refs/rad/id

We move the signed refs branch to:

  refs/rad/sigrefs

Keeping both "special" branches under the same hierarchy makes things a
bit easier to work with, and tells the user that they should be updated
with special tooling.

We also revert to `rad/` because we no longer have the issue of having
`rad/rad/id` when doing a checkout of the remote branch in a working
copy.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-11-01 15:56:06 +01:00
Fintan Halpenny c0b0d29e19
radicle-crypto: split out from radicle
The crypto types are useful to use in other components that are
separate from the radicle crate, e.g. the incoming radicle-cobs
crate.

Separate out the types into a radicle-crypto crate. This crate defines
the usual PublicKey, SecretKey, and Signature types. It also provides
the ssh functionality, under the `ssh` feature. It is also necessary
to provide the `From` impl for `Component` here, which again is
guarded by the `git-ref-format` feature.

The `Arbitrary` implementation are moved. The arbitrary decision of
redefining `ByteArray` in both radicle-crypto and radicle was made.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
2022-10-27 20:40:39 +01:00
Alexis Sellier 3bff9a9dc1
Set repository canonical refs
We set the `HEAD` and eg. `refs/heads/master` refs when updating
repositories, which allows users to easily clone with git.

For now, `HEAD` is chosen based on a unanimity quorum of delegates.
This can be made more sophisticated in the future.

We've also had to ignore some refs during verification, since these
have cropped in for eg. due to the staging copy clone and the
changes included here.

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-19 10:27:24 +02:00
Fintan Halpenny df15b497ab
radicle: namespace peers
The previous iteration of the storage layout for projects organised
peer's subtrees by the `refs/remotes` category. This layout leads to
problems when linking a working copy to the storage project. The fetch
refspec would look something like:

  fetch = +refs/remotes/abc/heads/*:refs/remotes/rad/*

This works perfectly fine when running:

  git fetch rad

but will fail when one tries to specify:

  git fetch rad main

Instead, the command would need to be:

  git fetch remotes/abc/heads/main

This patch proposes to move the use of `refs/namespaces` for each
peer. The layout looks similar in that each peer has a subtree, but
instead it is under `refs/namespaces/<peer>/refs/...`.

The previous refspec would look more familiar in its new form:

  fetch = +refs/heads/*:refs/remotes/rad/*

With this in place running:

  git --namespace=abc rad main

Will work as expected and place the reference under
`refs/remotes/rad/main`. Similary, `git --namespace=abc push` will
work as expected.

Another benefit of this approach is that the use of namespacing means
that a tag is pushed it will be placed under the respective namespace
rather than in the global `refs/tags` category.

The actual implementation needed to work around the fact that
`git2`/`libgit2` does not have any options for fetching or pushing
using namespaces. The working copy code uses processes to shell out to
`git` for namespacing needs.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
2022-10-12 12:30:05 +02:00
Alexis Sellier a104f9681c
Warn on `unwrap`, remove last remaining instances
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-11 09:31:54 +02:00
Alexis Sellier 6ef74c6674
Don't nest options inside results
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-11 09:31:52 +02:00
Alexis Sellier fde0af09f7
Handle errors correctly in storage
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-10-11 09:31:48 +02:00
Slack Coder f9ad3ac155 git: Use RefString types for git::refs
Lean on rust's type system to improve safety.

Signed-off-by: Slack Coder <slackcoder@server.ky>
2022-09-28 16:11:03 -05:00
Alexis Sellier 27e39c0df5
Make `Id` a `Copy` 2022-09-27 14:13:20 +02:00
Alexis Sellier fcb1007f9d
Refactor service
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-23 15:43:55 +02:00
Alexis Sellier 51f2d4e3fc
Move identity types to project
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-22 16:31:58 +02:00
Alexis Sellier 62408234cf
Rename `doc` module to `project`
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-22 16:02:42 +02:00
Alexis Sellier e382bc4eb9
Remove `Project` type
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-22 15:59:20 +02:00
Alexis Sellier f5bfb8d90a
radicle: Implement canonical fork
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-21 16:08:04 +02:00
Alexis Sellier 46501507be
Split repository into two creates
* `radicle`: core library
* `radicle-node`: node

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
2022-09-21 15:11:17 +02:00