Add credential-management-proto crate

The credential-management-proto crate provides types and traits for
implementing the w3c CredentialManagement API
dev
Nick Zana 1 year ago
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