lb_rs/model/
api.rs

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