system.go raw
1 package mailinabox
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7 "net/url"
8 "strconv"
9 "strings"
10 )
11
12 // SystemStatus Represents a system status.
13 type SystemStatus struct {
14 Type string `json:"type,omitempty"`
15 Text string `json:"text,omitempty"`
16 Extra []ExtraStatus `json:"extra,omitempty"`
17 }
18
19 // ExtraStatus Represents extra status.
20 type ExtraStatus struct {
21 Monospace bool `json:"monospace,omitempty"`
22 Text string `json:"text,omitempty"`
23 }
24
25 // BackupStatus Represents a backup status.
26 type BackupStatus struct {
27 Backups []Backup `json:"backups,omitempty"`
28 UnmatchedFileSize int `json:"unmatched_file_size,omitempty"`
29 Error string `json:"error,omitempty"`
30 }
31
32 // Backup Represents a backup.
33 type Backup struct {
34 Date string `json:"date,omitempty"`
35 DateDelta string `json:"date_delta,omitempty"`
36 DateStr string `json:"date_str,omitempty"`
37 DeletedIn string `json:"deleted_in,omitempty"`
38 Full bool `json:"full,omitempty"`
39 Size int `json:"size,omitempty"`
40 Volumes int `json:"volumes,omitempty"`
41 }
42
43 // BackupConfig Represents a backup configuration.
44 type BackupConfig struct {
45 EncPwFile string `json:"enc_pw_file,omitempty"`
46 FileTargetDirectory string `json:"file_target_directory,omitempty"`
47 MinAgeInDays int `json:"min_age_in_days,omitempty"`
48 SSHPubKey string `json:"ssh_pub_key,omitempty"`
49 Target string `json:"target,omitempty"`
50 TargetUser string `json:"target_user,omitempty"`
51 TargetPass string `json:"target_pass,omitempty"`
52 }
53
54 // SystemService System API.
55 // https://mailinabox.email/api-docs.html#tag/System
56 type SystemService service
57
58 // GetStatus Returns an array of statuses which can include headings.
59 // https://mailinabox.email/api-docs.html#operation/getSystemStatus
60 func (s *SystemService) GetStatus(ctx context.Context) ([]SystemStatus, error) {
61 endpoint := s.client.baseURL.JoinPath("admin", "system", "status")
62
63 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), http.NoBody)
64 if err != nil {
65 return nil, fmt.Errorf("unable to create request: %w", err)
66 }
67
68 var results []SystemStatus
69
70 err = s.client.doJSON(req, &results)
71 if err != nil {
72 return nil, err
73 }
74
75 return results, nil
76 }
77
78 // GetVersion Returns installed Mail-in-a-Box version.
79 // https://mailinabox.email/api-docs.html#operation/getSystemVersion
80 func (s *SystemService) GetVersion(ctx context.Context) (string, error) {
81 endpoint := s.client.baseURL.JoinPath("admin", "system", "version")
82
83 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
84 if err != nil {
85 return "", fmt.Errorf("unable to create request: %w", err)
86 }
87
88 resp, err := s.client.doPlain(req)
89 if err != nil {
90 return "", err
91 }
92
93 return strings.TrimSpace(string(resp)), nil
94 }
95
96 // GetUpstreamVersion Returns Mail-in-a-Box upstream version.
97 // https://mailinabox.email/api-docs.html#operation/getSystemUpstreamVersion
98 func (s *SystemService) GetUpstreamVersion(ctx context.Context) (string, error) {
99 endpoint := s.client.baseURL.JoinPath("admin", "system", "latest-upstream-version")
100
101 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), http.NoBody)
102 if err != nil {
103 return "", fmt.Errorf("unable to create request: %w", err)
104 }
105
106 resp, err := s.client.doPlain(req)
107 if err != nil {
108 return "", err
109 }
110
111 return strings.TrimSpace(string(resp)), nil
112 }
113
114 // GetUpdates Returns system (apt) updates.
115 // https://mailinabox.email/api-docs.html#operation/getSystemUpdates
116 func (s *SystemService) GetUpdates(ctx context.Context) ([]string, error) {
117 endpoint := s.client.baseURL.JoinPath("admin", "system", "updates")
118
119 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
120 if err != nil {
121 return nil, fmt.Errorf("unable to create request: %w", err)
122 }
123
124 resp, err := s.client.doPlain(req)
125 if err != nil {
126 return nil, err
127 }
128
129 updates := strings.Split(strings.TrimSpace(string(resp)), "\n")
130
131 return updates, nil
132 }
133
134 // UpdatePackages Updates system (apt) packages.
135 // https://mailinabox.email/api-docs.html#operation/getSystemUpdates
136 func (s *SystemService) UpdatePackages(ctx context.Context) (string, error) {
137 endpoint := s.client.baseURL.JoinPath("admin", "system", "update-packages")
138
139 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), http.NoBody)
140 if err != nil {
141 return "", fmt.Errorf("unable to create request: %w", err)
142 }
143
144 resp, err := s.client.doPlain(req)
145 if err != nil {
146 return "", err
147 }
148
149 return strings.TrimSpace(string(resp)), nil
150 }
151
152 // GetPrivacyStatus Returns system privacy (new-version check) status.
153 // https://mailinabox.email/api-docs.html#operation/getSystemPrivacyStatus
154 func (s *SystemService) GetPrivacyStatus(ctx context.Context) (bool, error) {
155 endpoint := s.client.baseURL.JoinPath("admin", "system", "privacy")
156
157 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
158 if err != nil {
159 return false, fmt.Errorf("unable to create request: %w", err)
160 }
161
162 var result bool
163
164 err = s.client.doJSON(req, &result)
165 if err != nil {
166 return false, err
167 }
168
169 return result, nil
170 }
171
172 // UpdatePrivacyStatus Updates system privacy (new-version checks).
173 // - value: `private`: Disable new version checks
174 // - value: `off`: Enable new version checks
175 // https://mailinabox.email/api-docs.html#operation/updateSystemPrivacy
176 func (s *SystemService) UpdatePrivacyStatus(ctx context.Context, value string) (string, error) {
177 endpoint := s.client.baseURL.JoinPath("admin", "system", "privacy")
178
179 data := url.Values{}
180 data.Set("value", value)
181
182 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), strings.NewReader(data.Encode()))
183 if err != nil {
184 return "", fmt.Errorf("unable to create request: %w", err)
185 }
186
187 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
188
189 resp, err := s.client.doPlain(req)
190 if err != nil {
191 return "", err
192 }
193
194 return strings.TrimSpace(string(resp)), nil
195 }
196
197 // GetRebootStatus Returns the system reboot status.
198 // https://mailinabox.email/api-docs.html#operation/getSystemRebootStatus
199 func (s *SystemService) GetRebootStatus(ctx context.Context) (bool, error) {
200 endpoint := s.client.baseURL.JoinPath("admin", "system", "reboot")
201
202 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
203 if err != nil {
204 return false, fmt.Errorf("unable to create request: %w", err)
205 }
206
207 var result bool
208
209 err = s.client.doJSON(req, &result)
210 if err != nil {
211 return false, err
212 }
213
214 return result, nil
215 }
216
217 // Reboot Reboots the system.
218 // https://mailinabox.email/api-docs.html#operation/rebootSystem
219 func (s *SystemService) Reboot(ctx context.Context) (string, error) {
220 endpoint := s.client.baseURL.JoinPath("admin", "system", "reboot")
221
222 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), http.NoBody)
223 if err != nil {
224 return "", fmt.Errorf("unable to create request: %w", err)
225 }
226
227 resp, err := s.client.doPlain(req)
228 if err != nil {
229 return "", err
230 }
231
232 return strings.TrimSpace(string(resp)), nil
233 }
234
235 // GetBackupStatus Returns the system backup status.
236 // https://mailinabox.email/api-docs.html#operation/getSystemBackupStatus
237 func (s *SystemService) GetBackupStatus(ctx context.Context) (*BackupStatus, error) {
238 endpoint := s.client.baseURL.JoinPath("admin", "system", "backup", "status")
239
240 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
241 if err != nil {
242 return nil, fmt.Errorf("unable to create request: %w", err)
243 }
244
245 var result BackupStatus
246
247 err = s.client.doJSON(req, &result)
248 if err != nil {
249 return nil, err
250 }
251
252 return &result, nil
253 }
254
255 // GetBackupConfig Returns the system backup config.
256 // https://mailinabox.email/api-docs.html#operation/getSystemBackupConfig
257 func (s *SystemService) GetBackupConfig(ctx context.Context) (*BackupConfig, error) {
258 endpoint := s.client.baseURL.JoinPath("admin", "system", "backup", "config")
259
260 req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), http.NoBody)
261 if err != nil {
262 return nil, fmt.Errorf("unable to create request: %w", err)
263 }
264
265 var result BackupConfig
266
267 err = s.client.doJSON(req, &result)
268 if err != nil {
269 return nil, err
270 }
271
272 return &result, nil
273 }
274
275 // UpdateBackupConfig Updates the system backup config.
276 // https://mailinabox.email/api-docs.html#operation/updateSystemBackupConfig
277 func (s *SystemService) UpdateBackupConfig(ctx context.Context, target, targetUser, targetPass string, minAge int) (string, error) {
278 endpoint := s.client.baseURL.JoinPath("admin", "system", "backup", "config")
279
280 data := url.Values{}
281 data.Set("target", target)
282 data.Set("targetUser", targetUser)
283 data.Set("targetPass", targetPass)
284 data.Set("minAge", strconv.Itoa(minAge))
285
286 req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), strings.NewReader(data.Encode()))
287 if err != nil {
288 return "", fmt.Errorf("unable to create request: %w", err)
289 }
290
291 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
292
293 resp, err := s.client.doPlain(req)
294 if err != nil {
295 return "", err
296 }
297
298 return strings.TrimSpace(string(resp)), nil
299 }
300