Skip to main content

otter_support/
authproofs.rs

1// Copyright 2020-2021 Ian Jackson and contributors to Otter
2// SPDX-License-Identifier: AGPL-3.0-or-later
3// There is NO WARRANTY.
4
5use crate::prelude::*;
6
7#[derive(Copy,Clone,Debug)]
8pub struct Global;
9
10#[derive(Debug,Copy,Clone)]
11pub struct Unauthorised<T,A> (T, PhantomData<A>);
12impl<T,A> Unauthorised<T,A> {
13  #[inline] pub fn of(t: T) -> Self { Unauthorised(t, PhantomData) }
14  #[inline] pub fn by(self, _auth: Authorisation<A>) -> T { self.0 }
15  #[inline]
16  pub fn by_ref(&self,     _auth: Authorisation<A>) -> &    T { &    self.0 }
17  #[inline]
18  pub fn by_mut(&mut self, _auth: Authorisation<A>) -> &mut T { &mut self.0 }
19}
20impl<T,A> From<T> for Unauthorised<T,A> {
21  #[inline] fn from(t: T) -> Self { Self::of(t) }
22}
23
24#[derive(Error,Debug)]
25#[error("internal AuthorisationError {0}")]
26pub struct AuthorisationError(pub String);
27
28#[derive(Debug)]
29pub struct Authorisation<A> (PhantomData<*const A>);
30impl<A> Clone for Authorisation<A> { #[inline] fn clone(&self)->Self{ *self }}
31impl<A> Copy for Authorisation<A> { }
32
33pub type AuthorisationSuperuser = Authorisation<Global>;
34
35impl<T> Authorisation<T> {
36  /// Proof obligation: access to this `T` has been authorised.
37  #[inline]
38  pub const fn promise_for(_v: &T) -> Authorisation<T> {
39    Authorisation(PhantomData)
40  }
41  #[inline]
42  pub fn map<U,F>(self, _f: F) -> Authorisation<U> where F: Fn(&T) -> &U {
43    self.so_promise()
44  }
45  /// Minor proof obligation: in this case, authorised access to `T`
46  /// implies authorised access to `U`.
47  #[inline]
48  pub fn so_promise<U>(self) -> Authorisation<U> {
49    Authorisation(PhantomData)
50  }
51  /// Proof obligation: access to `T` has been authorised.
52  #[inline]
53  pub const fn promise_any() -> Authorisation<T> {
54    Authorisation(PhantomData)
55  }
56}
57
58impl<T:Serialize> From<Authorisation<Global>> for Authorisation<T> {
59  // ^ we need a bound not met by Global or we conflict with From<T> for T
60  #[inline]
61  fn from(global: Authorisation<Global>) -> Self {
62    global.so_promise()
63  }
64}
65
66impl From<anyhow::Error> for AuthorisationError {
67  fn from(a: anyhow::Error) -> AuthorisationError {
68    AuthorisationError(format!("{}", a))
69  }
70}
71
72pub trait AuthorisationCombine: Sized {
73  type Output;
74  #[inline]
75  fn combine(self) -> Authorisation<Self::Output> {
76    Authorisation(PhantomData)
77  }
78}
79impl<A,B> AuthorisationCombine
80  for (Authorisation<A>, Authorisation<B>) {
81  type Output = (A, B);
82}
83impl<A,B,C> AuthorisationCombine
84  for (Authorisation<A>, Authorisation<B>, Authorisation<C>) {
85  type Output = (A, B, C);
86}