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