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