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

iggy-rs / iggy / 13280939567

12 Feb 2025 08:18AM UTC coverage: 75.132% (-0.06%) from 75.192%
13280939567

Pull #1514

github

web-flow
Merge d9a2e8c28 into 19db87131
Pull Request #1514: Epilogue part 1

0 of 24 new or added lines in 2 files covered. (0.0%)

2 existing lines in 2 files now uncovered.

25022 of 33304 relevant lines covered (75.13%)

9818.21 hits per line

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

77.52
/server/src/streaming/systems/personal_access_tokens.rs
1
use crate::streaming::personal_access_tokens::personal_access_token::PersonalAccessToken;
2
use crate::streaming::session::Session;
3
use crate::streaming::systems::system::System;
4
use crate::streaming::systems::COMPONENT;
5
use crate::streaming::users::user::User;
6
use error_set::ErrContext;
7
use iggy::error::IggyError;
8
use iggy::utils::expiry::IggyExpiry;
9
use iggy::utils::timestamp::IggyTimestamp;
10
use tracing::{error, info};
11

12
impl System {
13
    pub async fn get_personal_access_tokens(
26✔
14
        &self,
26✔
15
        session: &Session,
26✔
16
    ) -> Result<Vec<&PersonalAccessToken>, IggyError> {
26✔
17
        self.ensure_authenticated(session)?;
26✔
18
        let user_id = session.get_user_id();
26✔
19
        let user = self
26✔
20
            .get_user(&user_id.try_into()?)
26✔
21
            .with_error_context(|_| {
26✔
22
                format!("{COMPONENT} - failed to get user with id: {user_id}")
×
23
            })?;
26✔
24
        info!("Loading personal access tokens for user with ID: {user_id}...",);
26✔
25
        let personal_access_tokens: Vec<_> = user.personal_access_tokens.values().collect();
26✔
26
        info!(
26✔
27
            "Loaded {} personal access tokens for user with ID: {user_id}.",
×
28
            personal_access_tokens.len(),
×
29
        );
30
        Ok(personal_access_tokens)
26✔
31
    }
26✔
32

33
    pub async fn create_personal_access_token(
20✔
34
        &mut self,
20✔
35
        session: &Session,
20✔
36
        name: &str,
20✔
37
        expiry: IggyExpiry,
20✔
38
    ) -> Result<String, IggyError> {
20✔
39
        self.ensure_authenticated(session)?;
20✔
40
        let user_id = session.get_user_id();
20✔
41
        let identifier = user_id.try_into()?;
20✔
42
        {
43
            let user = self.get_user(&identifier).with_error_context(|_| {
20✔
44
                format!("{COMPONENT} - failed to get user with id: {user_id}")
×
45
            })?;
20✔
46
            let max_token_per_user = self.personal_access_token.max_tokens_per_user;
20✔
47
            if user.personal_access_tokens.len() as u32 >= max_token_per_user {
20✔
48
                error!(
×
49
                "User with ID: {user_id} has reached the maximum number of personal access tokens: {max_token_per_user}.",
×
50
            );
51
                return Err(IggyError::PersonalAccessTokensLimitReached(
×
52
                    user_id,
×
53
                    max_token_per_user,
×
54
                ));
×
55
            }
20✔
56
        }
57

58
        let user = self.get_user_mut(&identifier).with_error_context(|_| {
20✔
59
            format!("{COMPONENT} - failed to get mutable reference to the user with id: {user_id}")
×
60
        })?;
20✔
61

62
        if user
20✔
63
            .personal_access_tokens
20✔
64
            .values()
20✔
65
            .any(|pat| pat.name == name)
20✔
66
        {
67
            error!("Personal access token: {name} for user with ID: {user_id} already exists.");
×
68
            return Err(IggyError::PersonalAccessTokenAlreadyExists(
×
69
                name.to_owned(),
×
70
                user_id,
×
71
            ));
×
72
        }
20✔
73

20✔
74
        info!("Creating personal access token: {name} for user with ID: {user_id}...");
20✔
75
        let (personal_access_token, token) =
20✔
76
            PersonalAccessToken::new(user_id, name, IggyTimestamp::now(), expiry);
20✔
77
        user.personal_access_tokens
20✔
78
            .insert(personal_access_token.token.clone(), personal_access_token);
20✔
79
        info!("Created personal access token: {name} for user with ID: {user_id}.");
20✔
80
        Ok(token)
20✔
81
    }
20✔
82

83
    pub async fn delete_personal_access_token(
19✔
84
        &mut self,
19✔
85
        session: &Session,
19✔
86
        name: &str,
19✔
87
    ) -> Result<(), IggyError> {
19✔
88
        self.ensure_authenticated(session)?;
19✔
89
        let user_id = session.get_user_id();
19✔
90
        let user = self
19✔
91
            .get_user_mut(&user_id.try_into()?)
19✔
92
            .with_error_context(|_| {
19✔
93
                format!(
×
94
                    "{COMPONENT} - failed to get mutable reference to the user with id: {user_id}"
×
95
                )
×
96
            })?;
19✔
97

98
        let token;
99

100
        {
101
            let pat = user
19✔
102
                .personal_access_tokens
19✔
103
                .iter()
19✔
104
                .find(|(_, pat)| pat.name == name);
20✔
105
            if pat.is_none() {
19✔
106
                error!("Personal access token: {name} for user with ID: {user_id} does not exist.",);
×
107
                return Err(IggyError::ResourceNotFound(name.to_owned()));
×
108
            }
19✔
109

19✔
110
            token = pat.unwrap().1.token.clone();
19✔
111
        }
19✔
112

19✔
113
        info!("Deleting personal access token: {name} for user with ID: {user_id}...");
19✔
114
        user.personal_access_tokens.remove(&token);
19✔
115
        info!("Deleted personal access token: {name} for user with ID: {user_id}.");
19✔
116
        Ok(())
19✔
117
    }
19✔
118

119
    pub async fn login_with_personal_access_token(
13✔
120
        &self,
13✔
121
        token: &str,
13✔
122
        session: Option<&Session>,
13✔
123
    ) -> Result<&User, IggyError> {
13✔
124
        let token_hash = PersonalAccessToken::hash_token(token);
13✔
125
        let mut personal_access_token = None;
13✔
126
        for user in self.users.values() {
13✔
127
            if let Some(pat) = user.personal_access_tokens.get(&token_hash) {
13✔
128
                personal_access_token = Some(pat);
13✔
129
                break;
13✔
UNCOV
130
            }
×
131
        }
132

133
        if personal_access_token.is_none() {
13✔
134
            error!("Personal access token: {} does not exist.", token);
×
135
            return Err(IggyError::ResourceNotFound(token.to_owned()));
×
136
        }
13✔
137

13✔
138
        let personal_access_token = personal_access_token.unwrap();
13✔
139
        if personal_access_token.is_expired(IggyTimestamp::now()) {
13✔
140
            error!(
1✔
141
                "Personal access token: {} for user with ID: {} has expired.",
×
142
                personal_access_token.name, personal_access_token.user_id
143
            );
144
            return Err(IggyError::PersonalAccessTokenExpired(
1✔
145
                personal_access_token.name.clone(),
1✔
146
                personal_access_token.user_id,
1✔
147
            ));
1✔
148
        }
12✔
149

150
        let user = self
12✔
151
            .get_user(&personal_access_token.user_id.try_into()?)
12✔
152
            .with_error_context(|_| {
12✔
153
                format!(
×
154
                    "{COMPONENT} - failed to get user with id: {}",
×
155
                    personal_access_token.user_id
×
156
                )
×
157
            })?;
12✔
158
        self.login_user_with_credentials(&user.username, None, session)
12✔
159
            .await
12✔
160
    }
13✔
161
}
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

© 2025 Coveralls, Inc