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  }