github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/jottacloud/api/types.go (about) 1 package api 2 3 import ( 4 "encoding/xml" 5 "fmt" 6 "time" 7 8 "github.com/pkg/errors" 9 ) 10 11 const ( 12 // default time format for almost all request and responses 13 timeFormat = "2006-01-02-T15:04:05Z0700" 14 // the API server seems to use a different format 15 apiTimeFormat = "2006-01-02T15:04:05Z07:00" 16 ) 17 18 // Time represents time values in the Jottacloud API. It uses a custom RFC3339 like format. 19 type Time time.Time 20 21 // UnmarshalXML turns XML into a Time 22 func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { 23 var v string 24 if err := d.DecodeElement(&v, &start); err != nil { 25 return err 26 } 27 if v == "" { 28 *t = Time(time.Time{}) 29 return nil 30 } 31 newTime, err := time.Parse(timeFormat, v) 32 if err == nil { 33 *t = Time(newTime) 34 } 35 return err 36 } 37 38 // MarshalXML turns a Time into XML 39 func (t *Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error { 40 return e.EncodeElement(t.String(), start) 41 } 42 43 // Return Time string in Jottacloud format 44 func (t Time) String() string { return time.Time(t).Format(timeFormat) } 45 46 // APIString returns Time string in Jottacloud API format 47 func (t Time) APIString() string { return time.Time(t).Format(apiTimeFormat) } 48 49 // LoginToken is struct representing the login token generated in the WebUI 50 type LoginToken struct { 51 Username string `json:"username"` 52 Realm string `json:"realm"` 53 WellKnownLink string `json:"well_known_link"` 54 AuthToken string `json:"auth_token"` 55 } 56 57 // WellKnown contains some configuration parameters for setting up endpoints 58 type WellKnown struct { 59 Issuer string `json:"issuer"` 60 AuthorizationEndpoint string `json:"authorization_endpoint"` 61 TokenEndpoint string `json:"token_endpoint"` 62 TokenIntrospectionEndpoint string `json:"token_introspection_endpoint"` 63 UserinfoEndpoint string `json:"userinfo_endpoint"` 64 EndSessionEndpoint string `json:"end_session_endpoint"` 65 JwksURI string `json:"jwks_uri"` 66 CheckSessionIframe string `json:"check_session_iframe"` 67 GrantTypesSupported []string `json:"grant_types_supported"` 68 ResponseTypesSupported []string `json:"response_types_supported"` 69 SubjectTypesSupported []string `json:"subject_types_supported"` 70 IDTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported"` 71 UserinfoSigningAlgValuesSupported []string `json:"userinfo_signing_alg_values_supported"` 72 RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"` 73 ResponseNodesSupported []string `json:"response_modes_supported"` 74 RegistrationEndpoint string `json:"registration_endpoint"` 75 TokenEndpointAuthMethodsSupported []string `json:"token_endpoint_auth_methods_supported"` 76 TokenEndpointAuthSigningAlgValuesSupported []string `json:"token_endpoint_auth_signing_alg_values_supported"` 77 ClaimsSupported []string `json:"claims_supported"` 78 ClaimTypesSupported []string `json:"claim_types_supported"` 79 ClaimsParameterSupported bool `json:"claims_parameter_supported"` 80 ScopesSupported []string `json:"scopes_supported"` 81 RequestParameterSupported bool `json:"request_parameter_supported"` 82 RequestURIParameterSupported bool `json:"request_uri_parameter_supported"` 83 CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"` 84 TLSClientCertificateBoundAccessTokens bool `json:"tls_client_certificate_bound_access_tokens"` 85 IntrospectionEndpoint string `json:"introspection_endpoint"` 86 } 87 88 // TokenJSON is the struct representing the HTTP response from OAuth2 89 // providers returning a token in JSON form. 90 type TokenJSON struct { 91 AccessToken string `json:"access_token"` 92 ExpiresIn int32 `json:"expires_in"` // at least PayPal returns string, while most return number 93 RefreshExpiresIn int32 `json:"refresh_expires_in"` 94 RefreshToken string `json:"refresh_token"` 95 TokenType string `json:"token_type"` 96 IDToken string `json:"id_token"` 97 NotBeforePolicy int32 `json:"not-before-policy"` 98 SessionState string `json:"session_state"` 99 Scope string `json:"scope"` 100 } 101 102 // JSON structures returned by new API 103 104 // AllocateFileRequest to prepare an upload to Jottacloud 105 type AllocateFileRequest struct { 106 Bytes int64 `json:"bytes"` 107 Created string `json:"created"` 108 Md5 string `json:"md5"` 109 Modified string `json:"modified"` 110 Path string `json:"path"` 111 } 112 113 // AllocateFileResponse for upload requests 114 type AllocateFileResponse struct { 115 Name string `json:"name"` 116 Path string `json:"path"` 117 State string `json:"state"` 118 UploadID string `json:"upload_id"` 119 UploadURL string `json:"upload_url"` 120 Bytes int64 `json:"bytes"` 121 ResumePos int64 `json:"resume_pos"` 122 } 123 124 // UploadResponse after an upload 125 type UploadResponse struct { 126 Name string `json:"name"` 127 Path string `json:"path"` 128 Kind string `json:"kind"` 129 ContentID string `json:"content_id"` 130 Bytes int64 `json:"bytes"` 131 Md5 string `json:"md5"` 132 Created int64 `json:"created"` 133 Modified int64 `json:"modified"` 134 Deleted interface{} `json:"deleted"` 135 Mime string `json:"mime"` 136 } 137 138 // DeviceRegistrationResponse is the response to registering a device 139 type DeviceRegistrationResponse struct { 140 ClientID string `json:"client_id"` 141 ClientSecret string `json:"client_secret"` 142 } 143 144 // CustomerInfo provides general information about the account. Required for finding the correct internal username. 145 type CustomerInfo struct { 146 Username string `json:"username"` 147 Email string `json:"email"` 148 Name string `json:"name"` 149 CountryCode string `json:"country_code"` 150 LanguageCode string `json:"language_code"` 151 CustomerGroupCode string `json:"customer_group_code"` 152 BrandCode string `json:"brand_code"` 153 AccountType string `json:"account_type"` 154 SubscriptionType string `json:"subscription_type"` 155 Usage int64 `json:"usage"` 156 Qouta int64 `json:"quota"` 157 BusinessUsage int64 `json:"business_usage"` 158 BusinessQouta int64 `json:"business_quota"` 159 WriteLocked bool `json:"write_locked"` 160 ReadLocked bool `json:"read_locked"` 161 LockedCause interface{} `json:"locked_cause"` 162 WebHash string `json:"web_hash"` 163 AndroidHash string `json:"android_hash"` 164 IOSHash string `json:"ios_hash"` 165 } 166 167 // TrashResponse is returned when emptying the Trash 168 type TrashResponse struct { 169 Folders int64 `json:"folders"` 170 Files int64 `json:"files"` 171 } 172 173 // XML structures returned by the old API 174 175 // Flag is a hacky type for checking if an attribute is present 176 type Flag bool 177 178 // UnmarshalXMLAttr sets Flag to true if the attribute is present 179 func (f *Flag) UnmarshalXMLAttr(attr xml.Attr) error { 180 *f = true 181 return nil 182 } 183 184 // MarshalXMLAttr : Do not use 185 func (f *Flag) MarshalXMLAttr(name xml.Name) (xml.Attr, error) { 186 attr := xml.Attr{ 187 Name: name, 188 Value: "false", 189 } 190 return attr, errors.New("unimplemented") 191 } 192 193 /* 194 GET http://www.jottacloud.com/JFS/<account> 195 196 <user time="2018-07-18-T21:39:10Z" host="dn-132"> 197 <username>12qh1wsht8cssxdtwl15rqh9</username> 198 <account-type>free</account-type> 199 <locked>false</locked> 200 <capacity>5368709120</capacity> 201 <max-devices>-1</max-devices> 202 <max-mobile-devices>-1</max-mobile-devices> 203 <usage>0</usage> 204 <read-locked>false</read-locked> 205 <write-locked>false</write-locked> 206 <quota-write-locked>false</quota-write-locked> 207 <enable-sync>true</enable-sync> 208 <enable-foldershare>true</enable-foldershare> 209 <devices> 210 <device> 211 <name xml:space="preserve">Jotta</name> 212 <display_name xml:space="preserve">Jotta</display_name> 213 <type>JOTTA</type> 214 <sid>5c458d01-9eaf-4f23-8d3c-2486fd9704d8</sid> 215 <size>0</size> 216 <modified>2018-07-15-T22:04:59Z</modified> 217 </device> 218 </devices> 219 </user> 220 */ 221 222 // DriveInfo represents a Jottacloud account 223 type DriveInfo struct { 224 Username string `xml:"username"` 225 AccountType string `xml:"account-type"` 226 Locked bool `xml:"locked"` 227 Capacity int64 `xml:"capacity"` 228 MaxDevices int `xml:"max-devices"` 229 MaxMobileDevices int `xml:"max-mobile-devices"` 230 Usage int64 `xml:"usage"` 231 ReadLocked bool `xml:"read-locked"` 232 WriteLocked bool `xml:"write-locked"` 233 QuotaWriteLocked bool `xml:"quota-write-locked"` 234 EnableSync bool `xml:"enable-sync"` 235 EnableFolderShare bool `xml:"enable-foldershare"` 236 Devices []JottaDevice `xml:"devices>device"` 237 } 238 239 /* 240 GET http://www.jottacloud.com/JFS/<account>/<device> 241 242 <device time="2018-07-23-T20:21:50Z" host="dn-158"> 243 <name xml:space="preserve">Jotta</name> 244 <display_name xml:space="preserve">Jotta</display_name> 245 <type>JOTTA</type> 246 <sid>5c458d01-9eaf-4f23-8d3c-2486fd9704d8</sid> 247 <size>0</size> 248 <modified>2018-07-15-T22:04:59Z</modified> 249 <user>12qh1wsht8cssxdtwl15rqh9</user> 250 <mountPoints> 251 <mountPoint> 252 <name xml:space="preserve">Archive</name> 253 <size>0</size> 254 <modified>2018-07-15-T22:04:59Z</modified> 255 </mountPoint> 256 <mountPoint> 257 <name xml:space="preserve">Shared</name> 258 <size>0</size> 259 <modified></modified> 260 </mountPoint> 261 <mountPoint> 262 <name xml:space="preserve">Sync</name> 263 <size>0</size> 264 <modified></modified> 265 </mountPoint> 266 </mountPoints> 267 <metadata first="" max="" total="3" num_mountpoints="3"/> 268 </device> 269 */ 270 271 // JottaDevice represents a Jottacloud Device 272 type JottaDevice struct { 273 Name string `xml:"name"` 274 DisplayName string `xml:"display_name"` 275 Type string `xml:"type"` 276 Sid string `xml:"sid"` 277 Size int64 `xml:"size"` 278 User string `xml:"user"` 279 MountPoints []JottaMountPoint `xml:"mountPoints>mountPoint"` 280 } 281 282 /* 283 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint> 284 285 <mountPoint time="2018-07-24-T20:35:02Z" host="dn-157"> 286 <name xml:space="preserve">Sync</name> 287 <path xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta</path> 288 <abspath xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta</abspath> 289 <size>0</size> 290 <modified></modified> 291 <device>Jotta</device> 292 <user>12qh1wsht8cssxdtwl15rqh9</user> 293 <folders> 294 <folder name="test"/> 295 </folders> 296 <metadata first="" max="" total="1" num_folders="1" num_files="0"/> 297 </mountPoint> 298 */ 299 300 // JottaMountPoint represents a Jottacloud mountpoint 301 type JottaMountPoint struct { 302 Name string `xml:"name"` 303 Size int64 `xml:"size"` 304 Device string `xml:"device"` 305 Folders []JottaFolder `xml:"folders>folder"` 306 Files []JottaFile `xml:"files>file"` 307 } 308 309 /* 310 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint>/<folder> 311 312 <folder name="test" time="2018-07-24-T20:41:37Z" host="dn-158"> 313 <path xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta/Sync</path> 314 <abspath xml:space="preserve">/12qh1wsht8cssxdtwl15rqh9/Jotta/Sync</abspath> 315 <folders> 316 <folder name="t2"/>c 317 </folders> 318 <files> 319 <file name="block.csv" uuid="f6553cd4-1135-48fe-8e6a-bb9565c50ef2"> 320 <currentRevision> 321 <number>1</number> 322 <state>COMPLETED</state> 323 <created>2018-07-05-T15:08:02Z</created> 324 <modified>2018-07-05-T15:08:02Z</modified> 325 <mime>application/octet-stream</mime> 326 <size>30827730</size> 327 <md5>1e8a7b728ab678048df00075c9507158</md5> 328 <updated>2018-07-24-T20:41:10Z</updated> 329 </currentRevision> 330 </file> 331 </files> 332 <metadata first="" max="" total="2" num_folders="1" num_files="1"/> 333 </folder> 334 */ 335 336 // JottaFolder represents a JottacloudFolder 337 type JottaFolder struct { 338 XMLName xml.Name 339 Name string `xml:"name,attr"` 340 Deleted Flag `xml:"deleted,attr"` 341 Path string `xml:"path"` 342 CreatedAt Time `xml:"created"` 343 ModifiedAt Time `xml:"modified"` 344 Updated Time `xml:"updated"` 345 Folders []JottaFolder `xml:"folders>folder"` 346 Files []JottaFile `xml:"files>file"` 347 } 348 349 /* 350 GET http://www.jottacloud.com/JFS/<account>/<device>/<mountpoint>/.../<file> 351 352 <file name="block.csv" uuid="f6553cd4-1135-48fe-8e6a-bb9565c50ef2"> 353 <currentRevision> 354 <number>1</number> 355 <state>COMPLETED</state> 356 <created>2018-07-05-T15:08:02Z</created> 357 <modified>2018-07-05-T15:08:02Z</modified> 358 <mime>application/octet-stream</mime> 359 <size>30827730</size> 360 <md5>1e8a7b728ab678048df00075c9507158</md5> 361 <updated>2018-07-24-T20:41:10Z</updated> 362 </currentRevision> 363 </file> 364 */ 365 366 // JottaFile represents a Jottacloud file 367 type JottaFile struct { 368 XMLName xml.Name 369 Name string `xml:"name,attr"` 370 Deleted Flag `xml:"deleted,attr"` 371 PublicSharePath string `xml:"publicSharePath"` 372 State string `xml:"currentRevision>state"` 373 CreatedAt Time `xml:"currentRevision>created"` 374 ModifiedAt Time `xml:"currentRevision>modified"` 375 Updated Time `xml:"currentRevision>updated"` 376 Size int64 `xml:"currentRevision>size"` 377 MimeType string `xml:"currentRevision>mime"` 378 MD5 string `xml:"currentRevision>md5"` 379 } 380 381 // Error is a custom Error for wrapping Jottacloud error responses 382 type Error struct { 383 StatusCode int `xml:"code"` 384 Message string `xml:"message"` 385 Reason string `xml:"reason"` 386 Cause string `xml:"cause"` 387 } 388 389 // Error returns a string for the error and statistifes the error interface 390 func (e *Error) Error() string { 391 out := fmt.Sprintf("error %d", e.StatusCode) 392 if e.Message != "" { 393 out += ": " + e.Message 394 } 395 if e.Reason != "" { 396 out += fmt.Sprintf(" (%+v)", e.Reason) 397 } 398 return out 399 }