kustos_shared/
access.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// SPDX-FileCopyrightText: OpenTalk GmbH <mail@opentalk.eu>
//
// SPDX-License-Identifier: EUPL-1.2

use std::{fmt::Display, str::FromStr};

use crate::subject::ParsingError;

/// Permission access variants
///
/// Get, Put, Post, Delete are the respective HTTP methods.
/// The request middlewares are limited to these methods.
/// Read and Write can be used for more granular access when used with direct enforce calls.
#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash)]
pub enum AccessMethod {
    Read,
    Write,
    Get,
    Post,
    Put,
    Patch,
    Delete,
}

impl AccessMethod {
    pub const GET: AccessMethod = AccessMethod::Get;
    pub const POST: AccessMethod = AccessMethod::Post;
    pub const PUT: AccessMethod = AccessMethod::Put;
    pub const PATCH: AccessMethod = AccessMethod::Patch;
    pub const DELETE: AccessMethod = AccessMethod::Delete;

    pub fn all_http() -> [AccessMethod; 5] {
        [Self::GET, Self::POST, Self::PUT, Self::PATCH, Self::DELETE]
    }
}

impl FromStr for AccessMethod {
    type Err = ParsingError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s {
            "read" => AccessMethod::Read,
            "write" => AccessMethod::Write,
            "GET" => AccessMethod::Get,
            "POST" => AccessMethod::Post,
            "PUT" => AccessMethod::Put,
            "PATCH" => AccessMethod::Patch,
            "DELETE" => AccessMethod::Delete,
            _ => {
                return Err(ParsingError::InvalidAccessMethod {
                    method: s.to_owned(),
                })
            }
        })
    }
}

impl AsRef<str> for AccessMethod {
    fn as_ref(&self) -> &str {
        match self {
            AccessMethod::Read => "read",
            AccessMethod::Write => "write",
            AccessMethod::Get => "GET",
            AccessMethod::Post => "POST",
            AccessMethod::Patch => "PATCH",
            AccessMethod::Put => "PUT",
            AccessMethod::Delete => "DELETE",
        }
    }
}

impl Display for AccessMethod {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.as_ref())
    }
}

// TODO(r.floren) does this trait impl make any sense now?
impl From<AccessMethod> for [AccessMethod; 1] {
    fn from(val: AccessMethod) -> Self {
        [val]
    }
}

impl From<AccessMethod> for Vec<AccessMethod> {
    fn from(method: AccessMethod) -> Self {
        vec![method]
    }
}

impl From<http::Method> for AccessMethod {
    fn from(method: http::Method) -> Self {
        match method {
            http::Method::GET => Self::GET,
            http::Method::POST => Self::POST,
            http::Method::PATCH => Self::PATCH,
            http::Method::PUT => Self::PUT,
            http::Method::DELETE => Self::DELETE,
            _ => unimplemented!(),
        }
    }
}