mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-23 04:28:48 -05:00
193 lines
6.3 KiB
Go
193 lines
6.3 KiB
Go
package connector
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
|
)
|
|
|
|
// ConnectorResponse represent a response from the FileConnectorService.
|
|
// The ConnectorResponse is oriented to HTTP, so it has the Status, Headers
|
|
// and Body that the actual HTTP response should have. This includes HTTP
|
|
// errors with status 4xx and 5xx, which will also represent some error
|
|
// conditions for the FileConnectorService.
|
|
// Note that the Body is expected to be JSON-encoded outside before sending.
|
|
type ConnectorResponse struct {
|
|
Status int
|
|
Headers map[string]string
|
|
Body interface{}
|
|
}
|
|
|
|
// NewResponse creates a new ConnectorResponse with just the specified status.
|
|
// Headers and Body will be nil
|
|
func NewResponse(status int) *ConnectorResponse {
|
|
return &ConnectorResponse{Status: status}
|
|
}
|
|
|
|
// NewResponse creates a new ConnectorResponse with the specified status
|
|
// and the "X-WOPI-Lock" header having the value in the lockID parameter.
|
|
//
|
|
// This is usually used for conflict responses where the current lock id needs
|
|
// to be returned, although the `GetLock` method also uses this method for a
|
|
// successful response (with the lock id included)
|
|
func NewResponseWithLock(status int, lockID string) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: status,
|
|
Headers: map[string]string{
|
|
HeaderWopiLock: lockID,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewResponseLockConflict creates a new ConnectorResponse with the status 409
|
|
// and the "X-WOPI-Lock" header having the value in the lockID parameter.
|
|
//
|
|
// This is used for conflict responses where the current lock id needs
|
|
// to be returned, although the `GetLock` method also uses this method for a
|
|
// successful response (with the lock id included)
|
|
// The lockFailureReason parameter will be included in the "X-WOPI-LockFailureReason".
|
|
func NewResponseLockConflict(lockID string, lockFailureReason string) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: 409,
|
|
Headers: map[string]string{
|
|
HeaderWopiLock: lockID,
|
|
HeaderWopiLockFailureReason: lockFailureReason,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewResponseWithVersion creates a new ConnectorResponse with the specified status
|
|
// and the "X-WOPI-ItemVersion" header having the value in the mtime parameter.
|
|
func NewResponseWithVersion(mtime *types.Timestamp) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: 200,
|
|
Headers: map[string]string{
|
|
HeaderWopiVersion: getVersion(mtime),
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewResponseWithVersionAndLock creates a new ConnectorResponse with the specified status
|
|
// and the "X-WOPI-ItemVersion" header and the "X-WOPI-Lock" header
|
|
// having the values in the mtime and lockID parameters.
|
|
func NewResponseWithVersionAndLock(status int, mtime *types.Timestamp, lockID string) *ConnectorResponse {
|
|
r := &ConnectorResponse{
|
|
Status: status,
|
|
Headers: map[string]string{
|
|
HeaderWopiVersion: getVersion(mtime),
|
|
HeaderWopiLock: lockID,
|
|
},
|
|
}
|
|
return r
|
|
}
|
|
|
|
// NewResponseSuccessBody creates a new ConnectorResponse with a fixed 200
|
|
// (success) status and the specified body. The headers will be nil.
|
|
//
|
|
// This is used for the `CheckFileInfo` method in order to return the fileinfo
|
|
func NewResponseSuccessBody(body interface{}) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: 200,
|
|
Body: body,
|
|
}
|
|
}
|
|
|
|
// NewResponseSuccessBodyName creates a new ConnectorResponse with a fixed 200
|
|
// (success) status and a "map[string]interface{}" body. The body will contain
|
|
// a "Name" key with the supplied name as value.
|
|
//
|
|
// This is used for the `RenameFile` method in order to return the final name
|
|
// of the renamed file if the operation is successful
|
|
func NewResponseSuccessBodyName(name string) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: 200,
|
|
Body: map[string]interface{}{
|
|
"Name": name,
|
|
},
|
|
}
|
|
}
|
|
|
|
// NewResponseSuccessBodyNameUrl creates a new ConnectorResponse with a fixed
|
|
// 200 (success) status and a "map[string]interface{}" body. The body will
|
|
// contain "Name" and "Url" keys with their respective suplied values
|
|
//
|
|
// This is used in the `PutRelativeFile` methods (both suggested and relative).
|
|
func NewResponseSuccessBodyNameUrl(name, url string) *ConnectorResponse {
|
|
return &ConnectorResponse{
|
|
Status: 200,
|
|
Body: map[string]interface{}{
|
|
"Name": name,
|
|
"Url": url,
|
|
},
|
|
}
|
|
}
|
|
|
|
// ConnectorError defines an error in the connector. It contains an error code
|
|
// and a message.
|
|
// For convenience, the error code can be used as HTTP error code, although
|
|
// the connector shouldn't know anything about HTTP.
|
|
type ConnectorError struct {
|
|
HttpCodeOut int
|
|
Msg string
|
|
}
|
|
|
|
// Error gets the error message
|
|
func (e *ConnectorError) Error() string {
|
|
return e.Msg
|
|
}
|
|
|
|
// NewConnectorError creates a new connector error using the provided parameters
|
|
func NewConnectorError(code int, msg string) *ConnectorError {
|
|
return &ConnectorError{
|
|
HttpCodeOut: code,
|
|
Msg: msg,
|
|
}
|
|
}
|
|
|
|
// ConnectorService is the interface to implement the WOPI operations. They're
|
|
// divided into multiple endpoints.
|
|
// The IFileConnector will implement the "File" endpoint
|
|
// The IContentConnector will implement the "File content" endpoint
|
|
type ConnectorService interface {
|
|
GetFileConnector() FileConnectorService
|
|
GetContentConnector() ContentConnectorService
|
|
}
|
|
|
|
// Connector will implement the WOPI operations.
|
|
// For convenience, the connector splits the operations based on the
|
|
// WOPI endpoints, so you'll need to get the specific connector first.
|
|
//
|
|
// Available endpoints:
|
|
// * "Files" -> GetFileConnector()
|
|
// * "File contents" -> GetContentConnector()
|
|
//
|
|
// Other endpoints aren't available for now.
|
|
type Connector struct {
|
|
fileConnector FileConnectorService
|
|
contentConnector ContentConnectorService
|
|
}
|
|
|
|
// NewConnector creates a new connector
|
|
func NewConnector(fc FileConnectorService, cc ContentConnectorService) *Connector {
|
|
return &Connector{
|
|
fileConnector: fc,
|
|
contentConnector: cc,
|
|
}
|
|
}
|
|
|
|
// GetFileConnector gets the file connector service associated to this connector
|
|
func (c *Connector) GetFileConnector() FileConnectorService {
|
|
return c.fileConnector
|
|
}
|
|
|
|
// GetContentConnector gets the content connector service associated to this connector
|
|
func (c *Connector) GetContentConnector() ContentConnectorService {
|
|
return c.contentConnector
|
|
}
|
|
|
|
// getVersion returns a string representation of the timestamp
|
|
func getVersion(timestamp *types.Timestamp) string {
|
|
return "v" + strconv.FormatUint(timestamp.GetSeconds(), 10) +
|
|
strconv.FormatUint(uint64(timestamp.GetNanos()), 10)
|
|
}
|