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
use bytes::BufMut;

use super::stat::Stat;
use crate::acl::{Acl, AuthId, Permission};
use crate::chroot::ChrootPath;
use crate::record::{
    self,
    DeserializableRecord,
    DeserializeError,
    DynamicRecord,
    InvalidData,
    ReadingBuf,
    SerializableRecord,
};

impl SerializableRecord for Acl {
    fn serialize(&self, buf: &mut dyn BufMut) {
        buf.put_i32(self.permission().into_raw());
        self.scheme().serialize(buf);
        self.id().serialize(buf);
    }
}

impl DynamicRecord for Acl {
    fn serialized_len(&self) -> usize {
        return 4 + self.scheme().serialized_len() + self.id().serialized_len();
    }
}

impl TryFrom<i32> for Permission {
    type Error = InvalidData;

    fn try_from(raw: i32) -> Result<Permission, Self::Error> {
        let all_bits = Permission::ALL.into_raw();
        if (raw & !all_bits) != 0 {
            return Err(InvalidData::UnmarshalError(format!("invalid permission bits: {:#b}", raw)));
        }
        Ok(Permission::from_raw(raw))
    }
}

impl DeserializableRecord<'_> for Acl {
    type Error = DeserializeError;

    fn deserialize(buf: &mut ReadingBuf) -> Result<Self, Self::Error> {
        let perms = i32::deserialize(buf)?;
        let scheme: &str = record::deserialize(buf)?;
        let id: &str = record::deserialize(buf)?;
        let permission = Permission::try_from(perms)?;
        let auth_id = AuthId::new(scheme, id);
        Ok(Acl::new(permission, auth_id))
    }
}

pub struct SetAclRequest<'a> {
    pub path: ChrootPath<'a>,
    pub acl: &'a [Acl],
    pub version: i32,
}

impl SerializableRecord for SetAclRequest<'_> {
    fn serialize(&self, buf: &mut dyn BufMut) {
        self.path.serialize(buf);
        self.acl.serialize(buf);
        self.version.serialize(buf);
    }
}

impl DynamicRecord for SetAclRequest<'_> {
    fn serialized_len(&self) -> usize {
        self.path.serialized_len() + self.acl.serialized_len() + self.version.serialized_len()
    }
}

pub struct GetAclResponse {
    pub acl: Vec<Acl>,
    pub stat: Stat,
}

impl DeserializableRecord<'_> for GetAclResponse {
    type Error = DeserializeError;

    fn deserialize(buf: &mut ReadingBuf) -> Result<Self, Self::Error> {
        let acl = record::deserialize::<Vec<Acl>>(buf)?;
        let stat = record::deserialize::<Stat>(buf)?;
        Ok(GetAclResponse { acl, stat })
    }
}