• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polyphony-chat / sonata / 16254166328

13 Jul 2025 10:35PM UTC coverage: 82.155% (+18.8%) from 63.362%
16254166328

push

github

bitfl0wer
feat: late-night brainless tests and coverage

11 of 22 branches covered (50.0%)

Branch coverage included in aggregate %.

164 of 164 new or added lines in 4 files covered. (100.0%)

33 existing lines in 2 files now uncovered.

477 of 572 relevant lines covered (83.39%)

325.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.57
/src/database/models/mod.rs
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4

5
use chrono::NaiveDateTime;
6
use sqlx::{query, query_as, types::Uuid};
7

8
use crate::{
9
        database::Database,
10
        errors::{Context, Errcode, Error, SonataApiError, SonataDbError},
11
};
12

13
#[derive(sqlx::FromRow, sqlx::Type)]
14
pub struct PemEncoded(String);
15

16
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17
pub enum ActorType {
18
        Local,
19
        Foreign,
20
}
21

22
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
23
pub struct Actor {
24
        pub unique_actor_identifier: Uuid,
25
        r#type: ActorType,
26
}
27

28
impl From<LocalActor> for Actor {
UNCOV
29
        fn from(value: LocalActor) -> Self {
×
UNCOV
30
                Self { unique_actor_identifier: value.unique_actor_identifier, r#type: ActorType::Local }
×
UNCOV
31
        }
×
32
}
33

34
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
35
/// Actors from this home server.
36
pub struct LocalActor {
37
        /// The unique actor identifer. Does not change, even if the `local_name`
38
        /// changes.
39
        pub unique_actor_identifier: Uuid,
40
        /// The "local name" part of the actor. See the polyproto specification for
41
        /// more information.
42
        pub local_name: String,
43
        /// Whether this actors' account is currently deactivated.
44
        pub is_deactivated: bool,
45
        /// Timestamp from when the actor has first registered on the server, or
46
        /// when this account has been created.
47
        pub joined_at_timestamp: chrono::NaiveDateTime,
48
}
49

50
impl LocalActor {
51
        /// Tries to find an actor from the [Database] where `local_name` is equal
52
        /// to `name`, returning `None`, if such an actor does not exist.
53
        ///
54
        /// ## Errors
55
        ///
56
        /// Will error on Database connection issues and on other errors with the
57
        /// database, all of which are not in scope for this function to handle.
58
        pub async fn by_local_name(
×
59
                db: &Database,
×
UNCOV
60
                name: &str,
×
UNCOV
61
        ) -> Result<Option<LocalActor>, SonataDbError> {
×
UNCOV
62
                Ok(query!(
×
63
                        "
64
            SELECT uaid, local_name, deactivated, joined
65
            FROM local_actors
66
            WHERE local_name = $1
67
            LIMIT 1",
68
                        name
69
                )
70
                .fetch_optional(&db.pool)
×
71
                .await?
×
72
                .map(|record| LocalActor {
×
73
                        unique_actor_identifier: record.uaid,
×
74
                        local_name: record.local_name,
×
75
                        is_deactivated: record.deactivated,
×
UNCOV
76
                        joined_at_timestamp: record.joined,
×
UNCOV
77
                }))
×
UNCOV
78
        }
×
79

80
        /// Create a new [LocalActor] in the `local_actors` table of the [Database].
81
        /// Before creating, checks, if a user specified by `local_name` already
82
        /// exists in the table, returning an [Errcode::Duplicate]-type error, if
83
        /// this is the case.
84
        ///
85
        /// ## Errors
86
        ///
87
        /// Other than the above, this method will error, if something is wrong with
88
        /// the Database or Database connection.
UNCOV
89
        pub async fn create(db: &Database, local_name: &str) -> Result<LocalActor, SonataApiError> {
×
UNCOV
90
                if LocalActor::by_local_name(db, local_name).await?.is_some() {
×
UNCOV
91
                        Err(SonataApiError::Error(Error::new(
×
UNCOV
92
                                Errcode::Duplicate,
×
UNCOV
93
                                Some(Context::new(Some("local_name"), Some(local_name), None)),
×
UNCOV
94
                        )))
×
95
                } else {
UNCOV
96
                        let uaid = query!("INSERT INTO actors (type) VALUES ('local') RETURNING uaid")
×
UNCOV
97
                                .fetch_one(&db.pool)
×
UNCOV
98
                                .await
×
UNCOV
99
                                .map_err(SonataDbError::Sqlx)?;
×
UNCOV
100
                        Ok(query_as!(
×
101
                        LocalActor,
102
                        "INSERT INTO local_actors (uaid, local_name) VALUES ($1, $2) RETURNING uaid AS unique_actor_identifier, local_name, deactivated AS is_deactivated, joined AS joined_at_timestamp",
103
                        uaid.uaid,
104
                        local_name
UNCOV
105
                ).fetch_one(&db.pool).await.map_err(SonataDbError::Sqlx)?)
×
106
                }
UNCOV
107
        }
×
108
}
109

110
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
111
pub struct AlgorithmIdentifier {
112
        pub id: i32,
113
        pub algorithm_identifier_oid: String,
114
        pub common_name: Option<String>,
115
        pub parameters: Option<String>,
116
}
117

118
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
119
pub struct PublicKey {
120
        pub id: i64,
121
        pub belongs_to_actor_identifier: Uuid,
122
        pub public_key: String,
123
        pub algorithm_identifier_id: i32,
124
}
125

126
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
127
pub struct Subjects {
128
        pub actor_unique_identifier: Uuid,
129
        pub domain_components: Vec<String>,
130
        pub subject_x509_pem: PemEncoded,
131
}
132

133
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
134
pub struct Issuers {
135
        pub id: i64,
136
        pub domain_components: Vec<String>,
137
        pub issuer_x509_pem: PemEncoded,
138
}
139

140
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
141
pub struct IdCsr {
142
        pub internal_serial_number: Uuid,
143
        pub for_actor_uaid: Uuid,
144
        pub actor_public_key_id: i64,
145
        pub actor_signature: String,
146
        pub session_id: String, // TODO make this serialnumba
147
        pub valid_not_before: NaiveDateTime,
148
        pub valid_not_after: NaiveDateTime,
149
        pub extensions: String,
150
        pub pem_encoded: String,
151
}
152

153
#[derive(sqlx::Decode, sqlx::Encode, sqlx::FromRow)]
154
pub struct Invite {
155
        pub invite_link_owner: Option<Uuid>,
156
        pub usages_current: i32,
157
        pub usages_maximum: i32,
158
        pub invite_code: String,
159
        pub invalid: bool,
160
}
161

162
#[cfg(test)]
163
mod tests {
164
        use super::*;
165

166
        #[test]
167
        fn test_algorithm_identifier_creation() {
1✔
168
                let algo_id = AlgorithmIdentifier {
1✔
169
                        id: 1,
1✔
170
                        algorithm_identifier_oid: "1.2.840.113549.1.1.11".to_string(),
1✔
171
                        common_name: Some("SHA256withRSA".to_string()),
1✔
172
                        parameters: Some("null".to_string()),
1✔
173
                };
1✔
174

175
                assert_eq!(algo_id.id, 1);
1✔
176
                assert_eq!(algo_id.algorithm_identifier_oid, "1.2.840.113549.1.1.11");
1✔
177
                assert_eq!(algo_id.common_name, Some("SHA256withRSA".to_string()));
1✔
178
                assert_eq!(algo_id.parameters, Some("null".to_string()));
1✔
179
        }
1✔
180
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc