1use crate::error::Error;
2use crate::http_client::{get_slack_url, ResponseMetadata, SlackWebAPIClient};
3use crate::team::log::{Login, Paging};
4use serde::{Deserialize, Serialize};
5use serde_with::skip_serializing_none;
6
7#[skip_serializing_none]
8#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
9pub struct AccessLogsRequest {
10 pub before: Option<String>,
11 pub count: Option<String>,
12 pub page: Option<String>,
13 pub team_id: Option<String>,
14}
15
16#[skip_serializing_none]
17#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
18pub struct AccessLogsResponse {
19 pub ok: bool,
20 pub error: Option<String>,
21 pub response_metadata: Option<ResponseMetadata>,
22 pub logins: Option<Vec<Login>>,
23 pub paging: Option<Paging>,
24}
25
26pub async fn access_logs<T>(
27 client: &T,
28 param: &AccessLogsRequest,
29 bot_token: &str,
30) -> Result<AccessLogsResponse, Error>
31where
32 T: SlackWebAPIClient,
33{
34 let url = get_slack_url("team.accessLogs");
35 let json = serde_json::to_string(¶m)?;
36
37 client
38 .post_json(&url, &json, bot_token)
39 .await
40 .and_then(|result| {
41 serde_json::from_str::<AccessLogsResponse>(&result).map_err(Error::SerdeJsonError)
42 })
43}
44
45#[cfg(test)]
46mod test {
47 use super::*;
48 use crate::http_client::MockSlackWebAPIClient;
49
50 #[test]
51 fn convert_request() {
52 let request = AccessLogsRequest {
53 before: Some("1457989166".to_string()),
54 count: Some("20".to_string()),
55 page: Some("2".to_string()),
56 team_id: Some("T1234567890".to_string()),
57 };
58 let json = r##"{
59 "before": "1457989166",
60 "count": "20",
61 "page": "2",
62 "team_id": "T1234567890"
63}"##;
64
65 let j = serde_json::to_string_pretty(&request).unwrap();
66 assert_eq!(json, j);
67
68 let s = serde_json::from_str::<AccessLogsRequest>(json).unwrap();
69 assert_eq!(request, s);
70 }
71
72 #[test]
73 fn convert_response() {
74 let response = AccessLogsResponse {
75 ok: true,
76 logins: Some(vec![Login {
77 user_id: Some("U45678".to_string()),
78 username: Some("alice".to_string()),
79 date_first: Some(1422922864),
80 date_last: Some(1422922864),
81 count: Some(1),
82 ip: Some("127.0.0.1".to_string()),
83 user_agent: Some("SlackWeb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.35 Safari/537.36".to_string()),
84 isp: Some("BigCo ISP".to_string()),
85 country: Some("US".to_string()),
86 region: Some( "CA".to_string()),
87 }]),
88 paging: Some(Paging {
89 count: Some(100),
90 total: Some(2),
91 page: Some(1),
92 pages: Some(1),
93 }),
94 ..Default::default()
95 };
96 let json = r##"{
97 "ok": true,
98 "logins": [
99 {
100 "user_id": "U45678",
101 "username": "alice",
102 "date_first": 1422922864,
103 "date_last": 1422922864,
104 "count": 1,
105 "ip": "127.0.0.1",
106 "user_agent": "SlackWeb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.35 Safari/537.36",
107 "isp": "BigCo ISP",
108 "country": "US",
109 "region": "CA"
110 }
111 ],
112 "paging": {
113 "count": 100,
114 "total": 2,
115 "page": 1,
116 "pages": 1
117 }
118}"##;
119
120 let j = serde_json::to_string_pretty(&response).unwrap();
121 assert_eq!(json, j);
122
123 let s = serde_json::from_str::<AccessLogsResponse>(json).unwrap();
124 assert_eq!(response, s);
125 }
126
127 #[async_std::test]
128 async fn test_access_logs() {
129 let param = AccessLogsRequest {
130 before: Some("1457989166".to_string()),
131 count: Some("20".to_string()),
132 page: Some("2".to_string()),
133 team_id: Some("T1234567890".to_string()),
134 };
135 let mut mock = MockSlackWebAPIClient::new();
136 mock.expect_post_json().returning(|_, _, _| {
137 Ok(r##"{
138 "ok": true,
139 "logins": [
140 {
141 "user_id": "U45678",
142 "username": "alice",
143 "date_first": 1422922864,
144 "date_last": 1422922864,
145 "count": 1,
146 "ip": "127.0.0.1",
147 "user_agent": "SlackWeb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.35 Safari/537.36",
148 "isp": "BigCo ISP",
149 "country": "US",
150 "region": "CA"
151 }
152 ],
153 "paging": {
154 "count": 100,
155 "total": 2,
156 "page": 1,
157 "pages": 1
158 }
159}"##
160 .to_string())
161 });
162
163 let response = access_logs(&mock, ¶m, &"test_token".to_string())
164 .await
165 .unwrap();
166 let expect = AccessLogsResponse {
167 ok: true,
168 logins: Some(vec![Login {
169 user_id: Some("U45678".to_string()),
170 username: Some("alice".to_string()),
171 date_first: Some(1422922864),
172 date_last: Some(1422922864),
173 count: Some(1),
174 ip: Some("127.0.0.1".to_string()),
175 user_agent: Some("SlackWeb Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.35 Safari/537.36".to_string()),
176 isp: Some("BigCo ISP".to_string()),
177 country: Some("US".to_string()),
178 region: Some( "CA".to_string()),
179 }]),
180 paging: Some(Paging {
181 count: Some(100),
182 total: Some(2),
183 page: Some(1),
184 pages: Some(1),
185 }),
186 ..Default::default()
187 };
188
189 assert_eq!(expect, response);
190 }
191}