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