summaryrefslogtreecommitdiff
path: root/src/api/client_server/voip.rs
blob: 4990c17c4c31b647b83952337403299358bc1391 (plain)
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
use crate::{services, Result, Ruma};
use hmac::{Hmac, Mac};
use ruma::{api::client::voip::get_turn_server_info, SecondsSinceUnixEpoch};
use sha1::Sha1;
use std::time::{Duration, SystemTime};

type HmacSha1 = Hmac<Sha1>;

/// # `GET /_matrix/client/r0/voip/turnServer`
///
/// TODO: Returns information about the recommended turn server.
pub async fn turn_server_route(
    body: Ruma<get_turn_server_info::v3::Request>,
) -> Result<get_turn_server_info::v3::Response> {
    let sender_user = body.sender_user.as_ref().expect("user is authenticated");

    let turn_secret = services().globals.turn_secret().clone();

    let (username, password) = if !turn_secret.is_empty() {
        let expiry = SecondsSinceUnixEpoch::from_system_time(
            SystemTime::now() + Duration::from_secs(services().globals.turn_ttl()),
        )
        .expect("time is valid");

        let username: String = format!("{}:{}", expiry.get(), sender_user);

        let mut mac = HmacSha1::new_from_slice(turn_secret.as_bytes())
            .expect("HMAC can take key of any size");
        mac.update(username.as_bytes());

        let password: String = base64::encode_config(mac.finalize().into_bytes(), base64::STANDARD);

        (username, password)
    } else {
        (
            services().globals.turn_username().clone(),
            services().globals.turn_password().clone(),
        )
    };

    Ok(get_turn_server_info::v3::Response {
        username,
        password,
        uris: services().globals.turn_uris().to_vec(),
        ttl: Duration::from_secs(services().globals.turn_ttl()),
    })
}