1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::types::Server;
use crate::errors::Result;
#[cfg(feature = "server-aws")]
pub use crate::server::cloud::aws::AwsCredentials;
#[cfg(feature = "server-aws")]
use crate::server::cloud::aws::AwsService;
#[cfg(feature = "server-gcp")]
use crate::server::cloud::gcp::GcpService;
#[cfg(feature = "cloud")]
use crate::server::cloud::CloudServer;
use crate::server::local::LocalServer;
#[cfg(feature = "server-sync")]
use crate::server::sync::SyncServer;
use std::path::PathBuf;
#[cfg(feature = "server-sync")]
use uuid::Uuid;
/// The configuration for a replica's access to a sync server.
///
/// This enum is non-exhaustive, as users should only be constructing required
/// variants, not matching on it.
#[non_exhaustive]
pub enum ServerConfig {
/// A local task database, for situations with a single replica.
Local {
/// Path containing the server's DB
server_dir: PathBuf,
},
/// A remote taskchampion-sync-server instance
#[cfg(feature = "server-sync")]
Remote {
/// The base URL of the Sync server
url: String,
/// Client ID to identify and authenticate this replica to the server
client_id: Uuid,
/// Private encryption secret used to encrypt all data sent to the server. This can
/// be any suitably un-guessable string of bytes.
encryption_secret: Vec<u8>,
},
/// A Google Cloud Platform storage bucket.
#[cfg(feature = "server-gcp")]
Gcp {
/// Bucket in which to store the task data. This bucket must not be used for any other
/// purpose.
///
/// No special bucket configuration is reqiured.
bucket: String,
/// Path to a GCP credential file, in JSON format.
///
/// If `None`, then [Application Default
/// Credentials](https://cloud.google.com/docs/authentication/application-default-credentials)
/// are used. Typically these are associated with the user's Google Cloud account.
///
/// If `Some(path)`, then the path must be to a service account key. The service account
/// must have a role with the following permissions:
///
/// - storage.buckets.create
/// - storage.buckets.get
/// - storage.buckets.update
/// - storage.objects.create
/// - storage.objects.get
/// - storage.objects.list
/// - storage.objects.update
/// - storage.objects.delete
///
/// See the following GCP resources for more information:
/// - <https://cloud.google.com/docs/authentication#service-accounts>
/// - <https://cloud.google.com/iam/docs/keys-create-delete#creating>
credential_path: Option<String>,
/// Private encryption secret used to encrypt all data sent to the server. This can
/// be any suitably un-guessable string of bytes.
encryption_secret: Vec<u8>,
},
/// An Amazon Web Services storage bucket.
#[cfg(feature = "server-aws")]
Aws {
/// Region in which the bucket is located.
region: String,
/// Bucket in which to store the task data.
///
/// This bucket must not be used for any other purpose. No special bucket configuration is
/// required.
bucket: String,
/// Credential configuration for access to the bucket.
credentials: AwsCredentials,
/// Private encryption secret used to encrypt all data sent to the server. This can
/// be any suitably un-guessable string of bytes.
encryption_secret: Vec<u8>,
},
}
impl ServerConfig {
/// Get a server based on this configuration
pub fn into_server(self) -> Result<Box<dyn Server>> {
Ok(match self {
ServerConfig::Local { server_dir } => Box::new(LocalServer::new(server_dir)?),
#[cfg(feature = "server-sync")]
ServerConfig::Remote {
url,
client_id,
encryption_secret,
} => Box::new(SyncServer::new(url, client_id, encryption_secret)?),
#[cfg(feature = "server-gcp")]
ServerConfig::Gcp {
bucket,
credential_path,
encryption_secret,
} => Box::new(CloudServer::new(
GcpService::new(bucket, credential_path)?,
encryption_secret,
)?),
#[cfg(feature = "server-aws")]
ServerConfig::Aws {
region,
bucket,
credentials,
encryption_secret,
} => Box::new(CloudServer::new(
AwsService::new(region, bucket, credentials)?,
encryption_secret,
)?),
})
}
}