Skip to main content

lb_rs/model/
api.rs

1use crate::model::ValidationFailure;
2use crate::model::account::{Account, Username};
3use crate::model::crypto::*;
4use crate::model::file_metadata::{DocumentHmac, FileDiff, Owner};
5use crate::model::signed_file::SignedFile;
6use crate::service::debug::DebugInfo;
7use http::Method;
8use libsecp256k1::PublicKey;
9use serde::de::DeserializeOwned;
10use serde::{Deserialize, Serialize};
11use std::collections::{HashMap, HashSet};
12use std::fmt::Debug;
13use std::str::FromStr;
14use uuid::Uuid;
15
16use super::server_meta::ServerMeta;
17use super::signed_meta::SignedMeta;
18
19pub const FREE_TIER_USAGE_SIZE: u64 = 25000000;
20pub const PREMIUM_TIER_USAGE_SIZE: u64 = 30000000000;
21/// a fee of 1000 bytes allows 1000 file creations under the free tier.
22pub const METADATA_FEE: u64 = 1000;
23
24pub trait Request: Serialize + 'static {
25    type Response: Debug + DeserializeOwned + Clone;
26    type Error: Debug + DeserializeOwned + Clone;
27    const METHOD: Method;
28    const ROUTE: &'static str;
29}
30
31#[derive(Serialize, Deserialize, Debug, Clone)]
32pub struct RequestWrapper<T: Request> {
33    pub signed_request: ECSigned<T>,
34    pub client_version: String,
35}
36
37#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
38pub enum ErrorWrapper<E> {
39    Endpoint(E),
40    ClientUpdateRequired,
41    InvalidAuth,
42    ExpiredAuth,
43    InternalError,
44    BadRequest,
45}
46
47#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
48pub struct UpsertRequest {
49    pub updates: Vec<FileDiff<SignedFile>>,
50}
51
52impl Request for UpsertRequest {
53    type Response = ();
54    type Error = UpsertError;
55    const METHOD: Method = Method::POST;
56    const ROUTE: &'static str = "/upsert-file-metadata";
57}
58
59#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
60pub struct UpsertRequestV2 {
61    pub updates: Vec<FileDiff<SignedMeta>>,
62}
63
64impl Request for UpsertRequestV2 {
65    type Response = ();
66
67    type Error = UpsertError;
68    const METHOD: Method = Method::POST;
69    const ROUTE: &'static str = "/upsert-file-metadata-v2";
70}
71
72#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
73pub enum UpsertError {
74    /// Arises during a call to upsert, when the caller does not have the correct old version of the
75    /// File they're trying to modify
76    OldVersionIncorrect,
77
78    /// Arises during a call to upsert, when the old file is not known to the server
79    OldFileNotFound,
80
81    /// Arises during a call to upsert, when the caller suggests that a file is new, but the id already
82    /// exists
83    OldVersionRequired,
84
85    /// Arises during a call to upsert, when the person making the request is not an owner of the file
86    /// or has not signed the update
87    NotPermissioned,
88
89    /// Arises during a call to upsert, when a diff's new.id != old.id
90    DiffMalformed,
91
92    /// Metas in upsert cannot contain changes to digest
93    HmacModificationInvalid,
94
95    /// Metas in upsert cannot contain changes to doc size
96    SizeModificationInvalid,
97
98    RootModificationInvalid,
99
100    /// Found update to a deleted file
101    DeletedFileUpdated,
102
103    /// Over the User's Tier Limit
104    UsageIsOverDataCap,
105
106    /// Other misc validation failures
107    Validation(ValidationFailure),
108}
109
110#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
111pub struct ChangeDocRequest {
112    pub diff: FileDiff<SignedFile>,
113    pub new_content: EncryptedDocument,
114}
115
116#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
117pub struct ChangeDocRequestV2 {
118    pub diff: FileDiff<SignedMeta>,
119    pub new_content: EncryptedDocument,
120}
121
122#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
123pub enum ChangeDocError {
124    HmacMissing,
125    NewSizeIncorrect,
126    DocumentNotFound,
127    DocumentDeleted,
128    NotPermissioned,
129    OldVersionIncorrect,
130    DiffMalformed,
131    UsageIsOverDataCap,
132}
133
134impl Request for ChangeDocRequest {
135    type Response = ();
136    type Error = ChangeDocError;
137    const METHOD: Method = Method::PUT;
138    const ROUTE: &'static str = "/change-document-content";
139}
140
141impl Request for ChangeDocRequestV2 {
142    type Response = ();
143    type Error = ChangeDocError;
144    const METHOD: Method = Method::PUT;
145    const ROUTE: &'static str = "/change-document-content-v2";
146}
147
148#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
149pub struct GetDocRequest {
150    pub id: Uuid,
151    pub hmac: DocumentHmac,
152}
153
154#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
155pub struct GetDocumentResponse {
156    pub content: EncryptedDocument,
157}
158
159#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
160pub enum GetDocumentError {
161    DocumentNotFound,
162    NotPermissioned,
163    BandwidthExceeded,
164}
165
166impl Request for GetDocRequest {
167    type Response = GetDocumentResponse;
168    type Error = GetDocumentError;
169    const METHOD: Method = Method::GET;
170    const ROUTE: &'static str = "/get-document";
171}
172
173#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
174pub struct GetPublicKeyRequest {
175    pub username: String,
176}
177
178#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
179pub struct GetPublicKeyResponse {
180    pub key: PublicKey,
181}
182
183#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
184pub enum GetPublicKeyError {
185    InvalidUsername,
186    UserNotFound,
187}
188
189impl Request for GetPublicKeyRequest {
190    type Response = GetPublicKeyResponse;
191    type Error = GetPublicKeyError;
192    const METHOD: Method = Method::GET;
193    const ROUTE: &'static str = "/get-public-key";
194}
195
196#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
197pub struct GetUsernameRequest {
198    pub key: PublicKey,
199}
200
201#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
202pub struct GetUsernameResponse {
203    pub username: String,
204}
205
206#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
207pub enum GetUsernameError {
208    UserNotFound,
209}
210
211impl Request for GetUsernameRequest {
212    type Response = GetUsernameResponse;
213    type Error = GetUsernameError;
214    const METHOD: Method = Method::GET;
215    const ROUTE: &'static str = "/get-username";
216}
217
218#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
219pub struct GetUsageRequest {}
220
221#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
222pub struct GetUsageResponse {
223    pub usages: Vec<FileUsage>,
224    pub cap: u64,
225}
226
227impl GetUsageResponse {
228    pub fn sum_server_usage(&self) -> u64 {
229        self.usages.iter().map(|usage| usage.size_bytes).sum()
230    }
231}
232
233#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
234pub struct FileUsage {
235    pub file_id: Uuid,
236    pub size_bytes: u64,
237}
238
239#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
240pub enum GetUsageError {
241    UserNotFound,
242}
243
244impl Request for GetUsageRequest {
245    type Response = GetUsageResponse;
246    type Error = GetUsageError;
247    const METHOD: Method = Method::GET;
248    const ROUTE: &'static str = "/get-usage";
249}
250
251#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
252pub struct GetFileIdsRequest {}
253
254#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
255pub struct GetFileIdsResponse {
256    pub ids: HashSet<Uuid>,
257}
258
259#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
260pub enum GetFileIdsError {
261    UserNotFound,
262}
263
264impl Request for GetFileIdsRequest {
265    type Response = GetFileIdsResponse;
266    type Error = GetFileIdsError;
267    const METHOD: Method = Method::GET;
268    const ROUTE: &'static str = "/get-file-ids";
269}
270
271#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
272pub struct GetUpdatesRequest {
273    pub since_metadata_version: u64,
274}
275
276#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
277pub struct GetUpdatesRequestV2 {
278    pub since_metadata_version: u64,
279}
280
281#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
282pub struct GetUpdatesResponse {
283    pub as_of_metadata_version: u64,
284    pub file_metadata: Vec<SignedFile>,
285}
286
287#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
288pub struct GetUpdatesResponseV2 {
289    pub as_of_metadata_version: u64,
290    pub file_metadata: Vec<SignedMeta>,
291}
292
293#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
294pub enum GetUpdatesError {
295    UserNotFound,
296}
297
298impl Request for GetUpdatesRequest {
299    type Response = GetUpdatesResponse;
300    type Error = GetUpdatesError;
301    const METHOD: Method = Method::GET;
302    const ROUTE: &'static str = "/get-updates";
303}
304
305impl Request for GetUpdatesRequestV2 {
306    type Response = GetUpdatesResponseV2;
307    type Error = GetUpdatesError;
308    const METHOD: Method = Method::GET;
309    const ROUTE: &'static str = "/get-updates-v2";
310}
311
312#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
313pub struct NewAccountRequest {
314    pub username: Username,
315    pub public_key: PublicKey,
316    pub root_folder: SignedFile,
317}
318
319#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
320pub struct NewAccountRequestV2 {
321    pub username: Username,
322    pub public_key: PublicKey,
323    pub root_folder: SignedMeta,
324}
325
326impl NewAccountRequestV2 {
327    pub fn new(account: &Account, root_folder: &SignedMeta) -> Self {
328        let root_folder = root_folder.clone();
329        NewAccountRequestV2 {
330            username: account.username.clone(),
331            public_key: account.public_key(),
332            root_folder,
333        }
334    }
335}
336
337impl Request for NewAccountRequestV2 {
338    type Response = NewAccountResponse;
339    type Error = NewAccountError;
340    const METHOD: Method = Method::POST;
341    const ROUTE: &'static str = "/new-account-v2";
342}
343
344#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
345pub struct NewAccountResponse {
346    pub last_synced: u64,
347}
348
349#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
350pub enum NewAccountError {
351    UsernameTaken,
352    PublicKeyTaken,
353    InvalidUsername,
354    FileIdTaken,
355    Disabled,
356    RateLimited,
357}
358
359impl Request for NewAccountRequest {
360    type Response = NewAccountResponse;
361    type Error = NewAccountError;
362    const METHOD: Method = Method::POST;
363    const ROUTE: &'static str = "/new-account";
364}
365
366#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
367pub struct GetBuildInfoRequest {}
368
369#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
370pub enum GetBuildInfoError {}
371
372#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
373pub struct GetBuildInfoResponse {
374    pub build_version: String,
375    pub git_commit_hash: String,
376}
377
378impl Request for GetBuildInfoRequest {
379    type Response = GetBuildInfoResponse;
380    type Error = GetBuildInfoError;
381    const METHOD: Method = Method::GET;
382    const ROUTE: &'static str = "/get-build-info";
383}
384
385#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
386pub struct DeleteAccountRequest {}
387
388#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
389pub enum DeleteAccountError {
390    UserNotFound,
391}
392
393impl Request for DeleteAccountRequest {
394    type Response = ();
395    type Error = DeleteAccountError;
396    const METHOD: Method = Method::DELETE;
397    const ROUTE: &'static str = "/delete-account";
398}
399
400#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
401pub enum PaymentMethod {
402    NewCard { number: String, exp_year: i32, exp_month: i32, cvc: String },
403    OldCard,
404}
405
406#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
407pub enum StripeAccountTier {
408    Premium(PaymentMethod),
409}
410
411#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
412pub struct UpgradeAccountStripeRequest {
413    pub account_tier: StripeAccountTier,
414}
415
416#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
417pub struct UpgradeAccountStripeResponse {}
418
419#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
420pub enum UpgradeAccountStripeError {
421    OldCardDoesNotExist,
422    AlreadyPremium,
423    CardDecline,
424    InsufficientFunds,
425    TryAgain,
426    CardNotSupported,
427    ExpiredCard,
428    InvalidCardNumber,
429    InvalidCardExpYear,
430    InvalidCardExpMonth,
431    InvalidCardCvc,
432    ExistingRequestPending,
433    UserNotFound,
434}
435
436impl Request for UpgradeAccountStripeRequest {
437    type Response = UpgradeAccountStripeResponse;
438    type Error = UpgradeAccountStripeError;
439    const METHOD: Method = Method::POST;
440    const ROUTE: &'static str = "/upgrade-account-stripe";
441}
442
443#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
444pub struct UpgradeAccountGooglePlayRequest {
445    pub purchase_token: String,
446    pub account_id: String,
447}
448
449#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
450pub struct UpgradeAccountGooglePlayResponse {}
451
452#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
453pub enum UpgradeAccountGooglePlayError {
454    AlreadyPremium,
455    InvalidPurchaseToken,
456    ExistingRequestPending,
457    UserNotFound,
458}
459
460impl Request for UpgradeAccountGooglePlayRequest {
461    type Response = UpgradeAccountGooglePlayResponse;
462    type Error = UpgradeAccountGooglePlayError;
463    const METHOD: Method = Method::POST;
464    const ROUTE: &'static str = "/upgrade-account-google-play";
465}
466
467#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
468pub struct UpgradeAccountAppStoreRequest {
469    pub original_transaction_id: String,
470    pub app_account_token: String,
471}
472
473#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
474pub struct UpgradeAccountAppStoreResponse {}
475
476#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
477pub enum UpgradeAccountAppStoreError {
478    AppStoreAccountAlreadyLinked,
479    AlreadyPremium,
480    InvalidAuthDetails,
481    ExistingRequestPending,
482    UserNotFound,
483}
484
485impl Request for UpgradeAccountAppStoreRequest {
486    type Response = UpgradeAccountAppStoreResponse;
487    type Error = UpgradeAccountAppStoreError;
488    const METHOD: Method = Method::POST;
489    const ROUTE: &'static str = "/upgrade-account-app-store";
490}
491
492#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
493pub struct CancelSubscriptionRequest {}
494
495#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
496pub struct CancelSubscriptionResponse {}
497
498#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
499pub enum CancelSubscriptionError {
500    NotPremium,
501    AlreadyCanceled,
502    UsageIsOverFreeTierDataCap,
503    UserNotFound,
504    ExistingRequestPending,
505    CannotCancelForAppStore,
506}
507
508impl Request for CancelSubscriptionRequest {
509    type Response = CancelSubscriptionResponse;
510    type Error = CancelSubscriptionError;
511    const METHOD: Method = Method::DELETE;
512    const ROUTE: &'static str = "/cancel-subscription";
513}
514
515#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
516pub struct GetSubscriptionInfoRequest {}
517
518#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
519pub struct SubscriptionInfo {
520    pub payment_platform: PaymentPlatform,
521    pub period_end: UnixTimeMillis,
522}
523
524#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
525#[serde(tag = "tag")]
526pub enum PaymentPlatform {
527    Stripe { card_last_4_digits: String },
528    GooglePlay { account_state: GooglePlayAccountState },
529    AppStore { account_state: AppStoreAccountState },
530}
531
532#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
533pub struct GetSubscriptionInfoResponse {
534    pub subscription_info: Option<SubscriptionInfo>,
535}
536
537#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
538pub enum GetSubscriptionInfoError {
539    UserNotFound,
540}
541
542impl Request for GetSubscriptionInfoRequest {
543    type Response = GetSubscriptionInfoResponse;
544    type Error = GetSubscriptionInfoError;
545    const METHOD: Method = Method::GET;
546    const ROUTE: &'static str = "/get-subscription-info";
547}
548
549#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
550pub struct UpsertDebugInfoRequest {
551    pub debug_info: DebugInfo,
552}
553
554#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
555pub enum UpsertDebugInfoError {
556    NotPermissioned,
557}
558
559impl Request for UpsertDebugInfoRequest {
560    type Response = ();
561    type Error = UpsertDebugInfoError;
562    const METHOD: Method = Method::POST;
563    const ROUTE: &'static str = "/upsert-debug-info";
564}
565
566#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
567pub struct AdminDisappearAccountRequest {
568    pub username: String,
569}
570
571#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
572pub enum AdminDisappearAccountError {
573    NotPermissioned,
574    UserNotFound,
575}
576
577impl Request for AdminDisappearAccountRequest {
578    type Response = ();
579    type Error = AdminDisappearAccountError;
580    const METHOD: Method = Method::DELETE;
581    const ROUTE: &'static str = "/admin-disappear-account";
582}
583
584#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
585pub struct AdminDisappearFileRequest {
586    pub id: Uuid,
587}
588
589#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
590pub enum AdminDisappearFileError {
591    NotPermissioned,
592    FileNonexistent,
593    RootModificationInvalid,
594}
595
596impl Request for AdminDisappearFileRequest {
597    type Response = ();
598    type Error = AdminDisappearFileError;
599    const METHOD: Method = Method::DELETE;
600    const ROUTE: &'static str = "/admin-disappear-file";
601}
602
603#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
604pub struct AdminValidateAccountRequest {
605    pub username: String,
606}
607
608#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
609pub struct AdminValidateAccount {
610    pub tree_validation_failures: Vec<ValidationFailure>,
611    pub documents_missing_size: Vec<Uuid>,
612    pub documents_missing_content: Vec<Uuid>,
613}
614
615impl AdminValidateAccount {
616    pub fn is_empty(&self) -> bool {
617        self.tree_validation_failures.is_empty()
618            && self.documents_missing_content.is_empty()
619            && self.documents_missing_size.is_empty()
620    }
621}
622
623#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
624pub enum AdminValidateAccountError {
625    NotPermissioned,
626    UserNotFound,
627}
628
629impl Request for AdminValidateAccountRequest {
630    type Response = AdminValidateAccount;
631    type Error = AdminValidateAccountError;
632    const METHOD: Method = Method::GET;
633    const ROUTE: &'static str = "/admin-validate-account";
634}
635
636#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
637pub struct AdminValidateServerRequest {}
638
639#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)]
640pub struct AdminValidateServer {
641    // accounts
642    pub users_with_validation_failures: HashMap<Username, AdminValidateAccount>,
643    // index integrity
644    pub usernames_mapped_to_wrong_accounts: HashMap<String, String>,
645    // mapped username -> account username
646    pub usernames_mapped_to_nonexistent_accounts: HashMap<String, Owner>,
647    pub usernames_unmapped_to_accounts: HashSet<String>,
648    pub owners_mapped_to_unowned_files: HashMap<Owner, HashSet<Uuid>>,
649    pub owners_mapped_to_nonexistent_files: HashMap<Owner, HashSet<Uuid>>,
650    pub owners_unmapped_to_owned_files: HashMap<Owner, HashSet<Uuid>>,
651    pub owners_unmapped: HashSet<Owner>,
652    pub sharees_mapped_to_unshared_files: HashMap<Owner, HashSet<Uuid>>,
653    pub sharees_mapped_to_nonexistent_files: HashMap<Owner, HashSet<Uuid>>,
654    pub sharees_mapped_for_owned_files: HashMap<Owner, HashSet<Uuid>>,
655    pub sharees_mapped_for_deleted_files: HashMap<Owner, HashSet<Uuid>>,
656    pub sharees_unmapped_to_shared_files: HashMap<Owner, HashSet<Uuid>>,
657    pub sharees_unmapped: HashSet<Owner>,
658    pub files_mapped_as_parent_to_non_children: HashMap<Uuid, HashSet<Uuid>>,
659    pub files_mapped_as_parent_to_nonexistent_children: HashMap<Uuid, HashSet<Uuid>>,
660    pub files_mapped_as_parent_to_self: HashSet<Uuid>,
661    pub files_unmapped_as_parent_to_children: HashMap<Uuid, HashSet<Uuid>>,
662    pub files_unmapped_as_parent: HashSet<Uuid>,
663    pub sizes_mapped_for_files_without_hmac: HashSet<Uuid>,
664    pub sizes_mapped_for_nonexistent_files: HashSet<Uuid>,
665    pub sizes_unmapped_for_files_with_hmac: HashSet<Uuid>,
666    // document presence
667    pub files_with_hmacs_and_no_contents: HashSet<Uuid>,
668}
669
670#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
671pub enum AdminValidateServerError {
672    NotPermissioned,
673}
674
675impl Request for AdminValidateServerRequest {
676    type Response = AdminValidateServer;
677    type Error = AdminValidateServerError;
678    const METHOD: Method = Method::GET;
679    const ROUTE: &'static str = "/admin-validate-server";
680}
681
682#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
683pub struct AdminListUsersRequest {
684    pub filter: Option<AccountFilter>,
685}
686
687#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
688pub enum AccountFilter {
689    Premium,
690    AppStorePremium,
691    StripePremium,
692    GooglePlayPremium,
693}
694
695#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
696pub struct AdminListUsersResponse {
697    pub users: Vec<Username>,
698}
699
700#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
701pub enum AdminListUsersError {
702    NotPermissioned,
703}
704
705impl Request for AdminListUsersRequest {
706    type Response = AdminListUsersResponse;
707    type Error = AdminListUsersError;
708    const METHOD: Method = Method::GET;
709    const ROUTE: &'static str = "/admin-list-users";
710}
711
712#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
713pub struct AdminGetAccountInfoRequest {
714    pub identifier: AccountIdentifier,
715}
716
717#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
718pub enum AccountIdentifier {
719    PublicKey(PublicKey),
720    Username(Username),
721}
722
723#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
724pub struct AdminGetAccountInfoResponse {
725    pub account: AccountInfo,
726}
727
728#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
729pub struct AccountInfo {
730    pub username: String,
731    pub root: Uuid,
732    pub payment_platform: Option<PaymentPlatform>,
733    pub usage: String,
734}
735
736#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
737pub enum AdminGetAccountInfoError {
738    UserNotFound,
739    NotPermissioned,
740}
741
742impl Request for AdminGetAccountInfoRequest {
743    type Response = AdminGetAccountInfoResponse;
744    type Error = AdminGetAccountInfoError;
745    const METHOD: Method = Method::GET;
746    const ROUTE: &'static str = "/admin-get-account-info";
747}
748
749#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
750pub struct AdminFileInfoRequest {
751    pub id: Uuid,
752}
753
754#[derive(Serialize, Deserialize, Debug, Clone)]
755pub struct AdminFileInfoResponse {
756    pub file: ServerMeta,
757    pub ancestors: Vec<ServerMeta>,
758    pub descendants: Vec<ServerMeta>,
759}
760
761#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
762pub enum AdminFileInfoError {
763    NotPermissioned,
764    FileNonexistent,
765}
766
767impl Request for AdminFileInfoRequest {
768    type Response = AdminFileInfoResponse;
769    type Error = AdminFileInfoError;
770    const METHOD: Method = Method::GET;
771    const ROUTE: &'static str = "/admin-file-info";
772}
773
774#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
775pub enum AdminSetUserTierInfo {
776    Stripe {
777        customer_id: String,
778        customer_name: Uuid,
779        payment_method_id: String,
780        last_4: String,
781        subscription_id: String,
782        expiration_time: UnixTimeMillis,
783        account_state: StripeAccountState,
784    },
785
786    GooglePlay {
787        purchase_token: String,
788        expiration_time: UnixTimeMillis,
789        account_state: GooglePlayAccountState,
790    },
791
792    AppStore {
793        account_token: String,
794        original_transaction_id: String,
795        expiration_time: UnixTimeMillis,
796        account_state: AppStoreAccountState,
797    },
798
799    Free,
800}
801
802#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
803pub struct AdminSetUserTierRequest {
804    pub username: String,
805    pub info: AdminSetUserTierInfo,
806}
807
808#[derive(Serialize, Deserialize, Debug, Clone)]
809pub struct AdminSetUserTierResponse {}
810
811#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
812pub enum AdminSetUserTierError {
813    UserNotFound,
814    NotPermissioned,
815    ExistingRequestPending,
816}
817
818impl Request for AdminSetUserTierRequest {
819    type Response = AdminSetUserTierResponse;
820    type Error = AdminSetUserTierError;
821    const METHOD: Method = Method::POST;
822    const ROUTE: &'static str = "/admin-set-user-tier";
823}
824
825// number of milliseconds that have elapsed since the unix epoch
826pub type UnixTimeMillis = u64;
827
828#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Copy)]
829pub enum ServerIndex {
830    OwnedFiles,
831    SharedFiles,
832    FileChildren,
833}
834
835#[derive(Serialize, Deserialize, Debug, Clone)]
836pub struct AdminRebuildIndexRequest {
837    pub index: ServerIndex,
838}
839
840#[derive(Serialize, Deserialize, Debug, Clone)]
841pub enum AdminRebuildIndexError {
842    NotPermissioned,
843}
844
845impl Request for AdminRebuildIndexRequest {
846    type Response = ();
847    type Error = AdminRebuildIndexError;
848    const METHOD: Method = Method::POST;
849    const ROUTE: &'static str = "/admin-rebuild-index";
850}
851
852#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
853pub enum StripeAccountState {
854    Ok,
855    InvoiceFailed,
856    Canceled,
857}
858
859#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
860pub enum GooglePlayAccountState {
861    Ok,
862    Canceled,
863    GracePeriod,
864    OnHold,
865}
866
867#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
868pub enum AppStoreAccountState {
869    Ok,
870    GracePeriod,
871    FailedToRenew,
872    Expired,
873}
874
875impl FromStr for StripeAccountState {
876    type Err = ();
877
878    fn from_str(s: &str) -> Result<Self, Self::Err> {
879        match s {
880            "Ok" => Ok(StripeAccountState::Ok),
881            "Canceled" => Ok(StripeAccountState::Canceled),
882            "InvoiceFailed" => Ok(StripeAccountState::InvoiceFailed),
883            _ => Err(()),
884        }
885    }
886}
887
888impl FromStr for GooglePlayAccountState {
889    type Err = ();
890
891    fn from_str(s: &str) -> Result<Self, Self::Err> {
892        match s {
893            "Ok" => Ok(GooglePlayAccountState::Ok),
894            "Canceled" => Ok(GooglePlayAccountState::Canceled),
895            "GracePeriod" => Ok(GooglePlayAccountState::GracePeriod),
896            "OnHold" => Ok(GooglePlayAccountState::OnHold),
897            _ => Err(()),
898        }
899    }
900}
901
902impl FromStr for AppStoreAccountState {
903    type Err = ();
904
905    fn from_str(s: &str) -> Result<Self, Self::Err> {
906        match s {
907            "Ok" => Ok(AppStoreAccountState::Ok),
908            "Expired" => Ok(AppStoreAccountState::Expired),
909            "GracePeriod" => Ok(AppStoreAccountState::GracePeriod),
910            "FailedToRenew" => Ok(AppStoreAccountState::FailedToRenew),
911            _ => Err(()),
912        }
913    }
914}