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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use crate::{
AccessTokenRequest, AccessType, BCAuthorizeResponse, BcAuthorizeRequest, Environment,
OAuth2TokenResponse, TokenResponse,
};
pub struct Authorization {}
impl Authorization {
/// This operation is used to create an access token
///
/// # Parameters
///
/// * 'url', the url of the product to get balance from
/// * 'api_user', the api user of the installation
/// * 'api_key', the api key of the installation
/// * 'primary_key', the primary key of the installation
///
/// # Returns
///
/// * 'TokenResponse'
pub async fn create_access_token(
&self,
url: String,
api_user: String,
api_key: String,
primary_key: String,
) -> Result<TokenResponse, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let res = client
.post(format!("{}/token/", url))
.basic_auth(api_user, Some(api_key))
.header("Cache-Control", "no-cache")
.header("Content-type", "application/x-www-form-urlencoded")
.header("Ocp-Apim-Subscription-Key", &primary_key)
.header("Content-Length", "0")
.body("")
.send()
.await?;
if res.status().is_success() {
let body = res.text().await?;
let token_response: TokenResponse = serde_json::from_str(&body)?;
Ok(token_response)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
/// This operation is used to create an OAuth2 token
///
/// # Parameters
///
/// * 'url', the url of the product to get balance from
/// * 'api_user', the api user of the installation
/// * 'api_key', the api key of the installation
/// * 'primary_key', the primary key of the installation
/// * 'environment', the environement of the installation
/// * 'auth_req_id', this is the auth request id
///
/// # Returns
///
/// * 'OAuth2TokenResponse'
pub async fn create_o_auth_2_token(
&self,
url: String,
api_user: String,
api_key: String,
environment: Environment,
primary_key: String,
auth_req_id: String,
) -> Result<OAuth2TokenResponse, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let res = client
.post(format!("{}/oauth2/token/", url))
.basic_auth(api_user.to_string(), Some(api_key.to_string()))
.header("X-Target-Environment", environment.to_string())
.header("Content-type", "application/x-www-form-urlencoded")
.header("Ocp-Apim-Subscription-Key", &primary_key)
.body(AccessTokenRequest {
grant_type: "urn:openid:params:grant-type:ciba".to_string(),
auth_req_id,
})
.send()
.await?;
if res.status().is_success() {
let body = res.text().await?;
let token_response: OAuth2TokenResponse = serde_json::from_str(&body)?;
Ok(token_response)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
/// This operation is used to authorize a user.
///
/// # Parameters
/// * 'url', the url of the product to get balance from
/// * 'environment', the environment of the installation
/// * 'primary_key', the primary key of the installation
/// * 'access_token', the access token to be used to make the request
/// * 'msisdn', this is the phone number of the user
/// * 'callback_url', this is the url that will be used to notify the client of the status of the transaction
///
/// # Returns
///
/// * 'BCAuthorizeResponse'
pub async fn bc_authorize(
&self,
url: String,
environment: Environment,
primary_key: String,
msisdn: String,
callback_url: Option<&str>,
access_token: TokenResponse,
) -> Result<BCAuthorizeResponse, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let mut req = client
.post(format!("{}/v1_0/bc-authorize", url))
.bearer_auth(access_token.access_token)
.header("X-Target-Environment", environment.to_string())
.header("Content-type", "application/x-www-form-urlencoded")
.header("Ocp-Apim-Subscription-Key", &primary_key)
.body(
BcAuthorizeRequest {
login_hint: format!("ID:{}/MSISDN", msisdn),
scope: "profile".to_string(),
access_type: AccessType::Offline,
}
.to_string(),
);
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header("X-Callback-Url", callback_url);
}
}
let res = req.send().await?;
if res.status().is_success() {
let body = res.text().await?;
let token_response: BCAuthorizeResponse = serde_json::from_str(&body)?;
Ok(token_response)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
}