Add credential-management-proto crate

The credential-management-proto crate provides types and traits for
implementing the w3c CredentialManagement API
dev
Nick Zana
parent 4082fbb437
commit 89cf54df04
No known key found for this signature in database
GPG Key ID: 936524EE913D6538

@ -0,0 +1,2 @@
/target
/Cargo.lock

@ -0,0 +1,8 @@
[package]
name = "credential-management-proto"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

@ -0,0 +1,83 @@
use std::rc::Rc;
use crate::discovery;
#[derive(Clone)]
pub enum Type {
Federated,
Identity,
Otp,
Password,
PublicKey,
Other(Rc<str>),
}
impl AsRef<str> for Type {
fn as_ref(&self) -> &str {
match self {
Type::Federated => "federated",
Type::Identity => "identity",
Type::Otp => "otp",
Type::Password => "password",
Type::PublicKey => "public-key",
Type::Other(s) => s,
}
}
}
/// > <https://w3c.github.io/webappsec-credential-management/#the-credential-interface/>
pub trait Credential: Sized {
/// > The credentials identifier. The requirements for the identifier are
/// > distinct for each type of credential. It might represent a username
/// > for username/password tuples, for example.
// TODO: The specs declare this as a "USVString" (presumably
// "Unicode-Scalar-Value String"), which is subtly different from a typical
// Rust str/String (which I believe allows for non-scalar unicode
// sequences).
fn id(&self) -> &str;
/// > ...specifies the credential type represented by this object.
///
/// Conforming types must be able to provide a String representation of
/// their name to use as an identifier for the credential type.
fn credential_type() -> Type;
/// Origin-bound credentials can return the origin for which they are
/// effective, otherwise returns `None`.
// TODO: There's probably some structure to origins that can be encapsulated
// in the return type here
fn origin(&self) -> Option<&str>;
}
/// > Developers retrieve [`Credential`]s and interact with the user agents
/// > credential store via methods exposed on the [`Container`] interface, which
/// > hangs off the Navigator object as `navigator.credentials`.
/// >
/// > <https://w3c.github.io/webappsec-credential-management/#credentialscontainer/>
///
/// [`Container`]s are bound to a particular origin. Calls to associated
/// functions have an implicit restriction to be scoped to the particular origin
/// associated with the [`Container`].
pub trait Container {
type Credential: Credential;
type RequestOptions;
type CreateOptions;
const DISCOVERY_MODE: discovery::Mode;
async fn get(&self, options: Option<&Self::RequestOptions>) -> Option<Self::Credential>;
async fn store(&mut self, credential: Self::Credential)
-> Result<Self::Credential, StoreError>;
async fn create(&mut self, options: Option<&Self::CreateOptions>) -> Option<Self::Credential>;
async fn prevent_silent_access(&mut self);
async fn discover_from_external_source(
origin: &str,
options: &Self::RequestOptions,
same_origin_with_ancestors: bool,
) -> Result<std::collections::HashSet<Self::Credential>, discovery::Error>;
}
// TODO: More types of errors here
pub enum StoreError {
NotAllowed,
}

@ -0,0 +1,8 @@
#[derive(Clone, Copy)]
pub enum Mode {
CredentialStore,
Remote,
}
// TODO: Error types are not obviously specified in spec
pub enum Error {}

@ -0,0 +1,6 @@
#![feature(associated_const_equality, async_fn_in_trait)]
#![allow(clippy::missing_errors_doc, incomplete_features)]
pub mod credential;
pub mod discovery;
pub mod mediation;

@ -0,0 +1,36 @@
use crate::credential::Credential;
#[derive(Clone, Copy)]
// TODO: Add actual link for `get`
/// > When making a request via `get(options)`, developers can set a
/// > case-by-case requirement for user mediation by choosing the
/// > appropriate [`Requirement`] enum value.
/// >
/// > <https://w3c.github.io/webappsec-credential-management/#mediation-requirements/>
pub enum Requirement {
/// > User mediation is suppressed for the given operation. If the
/// > operation can be performed without user involvement, wonderful. If
/// > user involvement is necessary, then the operation will return null
/// > rather than involving the user.
Silent,
/// > If credentials can be handed over for a given operation without
/// > user mediation, they will be. If user mediation is required, then
/// > the user agent will involve the user in the decision.
Optional,
/// > Discovered credentials are presented to the user in a non-modal
/// > dialog along with an indication of the origin which is requesting
/// > credentials.
Conditional,
/// > The user agent will not hand over credentials without user
/// > mediation, even if the prevent silent access flag is unset for an
/// > origin.
Required,
}
/// Conformance to this trait indicates the Credential "...supports the
/// conditional approach to mediation of credential requests for the
/// credential type". This eliminates the need for the
/// `isConditionalMediationAvailable` function specified in the specs.
///
/// <https://w3c.github.io/webappsec-credential-management/#dom-credentialmediationrequirement-conditional/>
pub trait Conditional: Credential {}
Loading…
Cancel
Save