1 use anyhow
::{Error, format_err, bail}
;
4 use proxmox
::api
::{api, Router, RpcEnvironment, Permission}
;
7 use crate::tools
::subscription
::{self, SubscriptionStatus, SubscriptionInfo}
;
8 use crate::config
::acl
::{PRIV_SYS_AUDIT,PRIV_SYS_MODIFY}
;
9 use crate::config
::cached_user_info
::CachedUserInfo
;
10 use crate::api2
::types
::{NODE_SCHEMA, SUBSCRIPTION_KEY_SCHEMA, Authid}
;
19 description
: "Always connect to server, even if information in cache is up to date.",
28 permission
: &Permission
::Privilege(&["system"], PRIV_SYS_MODIFY
, false),
31 /// Check and update subscription status.
32 fn check_subscription(
34 ) -> Result
<(), Error
> {
35 // FIXME: drop once proxmox-api-macro is bumped to >> 5.0.0-1
36 let _remove_me
= API_METHOD_CHECK_SUBSCRIPTION_PARAM_DEFAULT_FORCE
;
38 let info
= match subscription
::read_subscription() {
39 Err(err
) => bail
!("could not read subscription status: {}", err
),
40 Ok(Some(info
)) => info
,
41 Ok(None
) => return Ok(()),
44 let server_id
= tools
::get_hardware_address()?
;
45 let key
= if let Some(key
) = info
.key
{
46 // always update apt auth if we have a key to ensure user can access enterprise repo
47 subscription
::update_apt_auth(Some(key
.to_owned()), Some(server_id
.to_owned()))?
;
53 if !force
&& info
.status
== SubscriptionStatus
::ACTIVE
{
54 let age
= proxmox
::tools
::time
::epoch_i64() - info
.checktime
.unwrap_or(i64::MAX
);
55 if age
< subscription
::MAX_LOCAL_KEY_AGE
{
60 let info
= subscription
::check_subscription(key
, server_id
)?
;
62 subscription
::write_subscription(info
)
63 .map_err(|e
| format_err
!("Error writing updated subscription status - {}", e
))?
;
77 description
: "Subscription status.",
78 type: SubscriptionInfo
,
81 permission
: &Permission
::Anybody
,
84 /// Read subscription info.
87 rpcenv
: &mut dyn RpcEnvironment
,
88 ) -> Result
<SubscriptionInfo
, Error
> {
89 let url
= "https://www.proxmox.com/en/proxmox-backup-server/pricing";
91 let info
= match subscription
::read_subscription() {
92 Err(err
) => bail
!("could not read subscription status: {}", err
),
93 Ok(Some(info
)) => info
,
94 Ok(None
) => SubscriptionInfo
{
95 status
: SubscriptionStatus
::NOTFOUND
,
96 message
: Some("There is no subscription key".into()),
97 serverid
: Some(tools
::get_hardware_address()?
),
98 url
: Some(url
.into()),
103 let auth_id
: Authid
= rpcenv
.get_auth_id().unwrap().parse()?
;
104 let user_info
= CachedUserInfo
::new()?
;
105 let user_privs
= user_info
.lookup_privs(&auth_id
, &[]);
107 if (user_privs
& PRIV_SYS_AUDIT
) == 0 {
108 // not enough privileges for full state
109 return Ok(SubscriptionInfo
{
111 message
: info
.message
,
127 schema
: SUBSCRIPTION_KEY_SCHEMA
,
133 permission
: &Permission
::Privilege(&["system"], PRIV_SYS_MODIFY
, false),
136 /// Set a subscription key and check it.
139 ) -> Result
<(), Error
> {
141 let server_id
= tools
::get_hardware_address()?
;
143 let info
= subscription
::check_subscription(key
, server_id
.to_owned())?
;
145 subscription
::write_subscription(info
)
146 .map_err(|e
| format_err
!("Error writing subscription status - {}", e
))?
;
161 permission
: &Permission
::Privilege(&["system"], PRIV_SYS_MODIFY
, false),
164 /// Delete subscription info.
165 fn delete_subscription() -> Result
<(), Error
> {
167 subscription
::delete_subscription()
168 .map_err(|err
| format_err
!("Deleting subscription failed: {}", err
))?
;
173 pub const ROUTER
: Router
= Router
::new()
174 .post(&API_METHOD_CHECK_SUBSCRIPTION
)
175 .put(&API_METHOD_SET_SUBSCRIPTION
)
176 .delete(&API_METHOD_DELETE_SUBSCRIPTION
)
177 .get(&API_METHOD_GET_SUBSCRIPTION
);