mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 20:29:54 -06:00
docs: add code documentation
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package connector
|
||||
|
||||
// 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
|
||||
@@ -16,6 +20,15 @@ func NewConnectorError(code int, msg string) *ConnectorError {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 *FileConnector
|
||||
contentConnector *ContentConnector
|
||||
|
||||
@@ -18,6 +18,10 @@ import (
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// ContentConnector implements the "File contents" endpoint.
|
||||
// Basically, the ContentConnector handles downloads (GetFile) and
|
||||
// uploads (PutFile)
|
||||
// Note that operations might return any kind of error, not just ConnectorError
|
||||
type ContentConnector struct {
|
||||
gwc gatewayv1beta1.GatewayAPIClient
|
||||
cfg *config.Config
|
||||
@@ -32,6 +36,13 @@ func NewContentConnector(gwc gatewayv1beta1.GatewayAPIClient, cfg *config.Config
|
||||
|
||||
// GetFile downloads the file from the storage
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/getfile
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// The contents of the file will be written directly into the writer passed as
|
||||
// parameter.
|
||||
func (c *ContentConnector) GetFile(ctx context.Context, writer io.Writer) error {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
@@ -138,6 +149,24 @@ func (c *ContentConnector) GetFile(ctx context.Context, writer io.Writer) error
|
||||
|
||||
// PutFile uploads the file to the storage
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/putfile
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// The contents of the file will be read from the stream. The full stream
|
||||
// length must be provided in order to upload the file.
|
||||
//
|
||||
// A lock ID must be provided for the upload (which must match the lock in the
|
||||
// file). The only case where an empty lock ID can be used is if the target
|
||||
// file has 0 size.
|
||||
//
|
||||
// This method will return the lock ID that should be returned in case of a
|
||||
// conflict, otherwise it will return an empty string. This means that if the
|
||||
// method returns a ConnectorError with code 409, the returned string is the
|
||||
// lock ID that should be used in the X-WOPI-Lock header. In other error
|
||||
// cases or if the method is successful, an empty string will be returned
|
||||
// (check for err != nil to know if something went wrong)
|
||||
func (c *ContentConnector) PutFile(ctx context.Context, stream io.Reader, streamLength int64, lockID string) (string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -38,6 +38,14 @@ func NewFileConnector(gwc gatewayv1beta1.GatewayAPIClient, cfg *config.Config) *
|
||||
|
||||
// GetLock returns a lock or an empty string if no lock exists
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/getlock
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// The lock ID applied to the file reference in the context will be returned
|
||||
// (if any). An error will be returned if something goes wrong. The error
|
||||
// could be a ConnectorError
|
||||
func (f *FileConnector) GetLock(ctx context.Context) (string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
@@ -80,6 +88,21 @@ func (f *FileConnector) GetLock(ctx context.Context) (string, error) {
|
||||
// Lock returns a WOPI lock or performs an unlock and relock
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/lock
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/unlockandrelock
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// Lock the file reference contained in the context with the provided lockID.
|
||||
// The oldLockID is only used for the "unlock and relock" operation. The "lock"
|
||||
// operation doesn't use the oldLockID and needs to be empty in this case.
|
||||
//
|
||||
// For the "lock" operation, if the operation is successful, an empty lock id
|
||||
// will be returned without any error. In case of conflict, the current lock
|
||||
// id will be returned along with a 409 ConnectorError. For any other error,
|
||||
// the method will return an empty lock id.
|
||||
//
|
||||
// For the "unlock and relock" operation, the behavior will be the same.
|
||||
func (f *FileConnector) Lock(ctx context.Context, lockID, oldLockID string) (string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
@@ -207,6 +230,17 @@ func (f *FileConnector) Lock(ctx context.Context, lockID, oldLockID string) (str
|
||||
|
||||
// RefreshLock refreshes a provided lock for 30 minutes
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/refreshlock
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// If the operation is successful, an empty lock id will be returned without
|
||||
// any error. In case of conflict, the current lock id will be returned
|
||||
// along with a 409 ConnectorError. For any other error, the method will
|
||||
// return an empty lock id.
|
||||
// The conflict happens if the provided lockID doesn't match the one actually
|
||||
// applied in the target file.
|
||||
func (f *FileConnector) RefreshLock(ctx context.Context, lockID string) (string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
@@ -304,6 +338,17 @@ func (f *FileConnector) RefreshLock(ctx context.Context, lockID string) (string,
|
||||
|
||||
// UnLock removes a given lock from a file
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/unlock
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// If the operation is successful, an empty lock id will be returned without
|
||||
// any error. In case of conflict, the current lock id will be returned
|
||||
// along with a 409 ConnectorError. For any other error, the method will
|
||||
// return an empty lock id.
|
||||
// The conflict happens if the provided lockID doesn't match the one actually
|
||||
// applied in the target file.
|
||||
func (f *FileConnector) UnLock(ctx context.Context, lockID string) (string, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
@@ -389,6 +434,13 @@ func (f *FileConnector) UnLock(ctx context.Context, lockID string) (string, erro
|
||||
|
||||
// CheckFileInfo returns information about the requested file and capabilities of the wopi server
|
||||
// https://docs.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/checkfileinfo
|
||||
//
|
||||
// The context MUST have a WOPI context, otherwise an error will be returned.
|
||||
// You can pass a pre-configured zerologger instance through the context that
|
||||
// will be used to log messages.
|
||||
//
|
||||
// If the operation is successful, a "FileInfo" instance will be returned,
|
||||
// otherwise the "FileInfo" will be empty and an error will be returned.
|
||||
func (f *FileConnector) CheckFileInfo(ctx context.Context) (FileInfo, error) {
|
||||
wopiContext, err := middleware.WopiContextFromCtx(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package connector
|
||||
|
||||
// FileInfo contains the properties of the file.
|
||||
// Some properties refer to capabilities in the WOPI client, and capabilities
|
||||
// that the WOPI server has.
|
||||
//
|
||||
// For now, the FileInfo contains data for Microsoft, Collabora and OnlyOffice.
|
||||
// Not all the properties are supported by every system.
|
||||
type FileInfo struct {
|
||||
// ------------
|
||||
// Microsoft WOPI check file info specification:
|
||||
|
||||
@@ -15,6 +15,14 @@ const (
|
||||
HeaderWopiOldLock string = "X-WOPI-OldLock"
|
||||
)
|
||||
|
||||
// HttpAdapter will adapt the responses from the connector to HTTP.
|
||||
//
|
||||
// The adapter will use the request's context for the connector operations,
|
||||
// this means that the request MUST have a valid WOPI context and a
|
||||
// pre-configured logger. This should have been prepared in the routing.
|
||||
//
|
||||
// All operations are expected to follow the definitions found in
|
||||
// https://learn.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/endpoints
|
||||
type HttpAdapter struct {
|
||||
con *Connector
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import (
|
||||
|
||||
var commonCS3ApiClient gatewayv1beta1.GatewayAPIClient
|
||||
|
||||
// GatewayAPIClient gets an instance based on the provided configuration.
|
||||
// The instance will be cached and returned if possible, unless the "forceNew"
|
||||
// parameter is set to true. In this case, the old instance will be replaced
|
||||
// with the new one if there is no error.
|
||||
func GetCS3apiClient(cfg *config.Config, forceNew bool) (gatewayv1beta1.GatewayAPIClient, error) {
|
||||
// establish a connection to the cs3 api endpoint
|
||||
// in this case a REVA gateway, started by oCIS
|
||||
|
||||
@@ -14,11 +14,20 @@ import (
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
||||
)
|
||||
|
||||
// RegisterOcisService will register this service.
|
||||
// There are no explicit requirements for the context, and it will be passed
|
||||
// without changes to the underlying RegisterService method.
|
||||
func RegisterOcisService(ctx context.Context, cfg *config.Config, logger log.Logger) error {
|
||||
svc := registry.BuildGRPCService(cfg.Service.Name, uuid.Must(uuid.NewV4()).String(), cfg.GRPC.Addr, "0.0.0")
|
||||
return registry.RegisterService(ctx, svc, logger)
|
||||
}
|
||||
|
||||
// RegisterAppProvider will register this service as app provider in REVA.
|
||||
// The GatewayAPIClient is expected to be provided via `helpers.GetCS3apiClient`.
|
||||
// The appUrls are expected to be provided via `helpers.GetAppURLs`
|
||||
//
|
||||
// Note that this method doesn't provide a re-registration mechanism, so it
|
||||
// will register the service once
|
||||
func RegisterAppProvider(
|
||||
ctx context.Context,
|
||||
cfg *config.Config,
|
||||
|
||||
@@ -39,7 +39,7 @@ func Config(val *config.Config) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// ViewUrl provides a function to set the ViewUrl option.
|
||||
// AppURLs provides a function to set the AppURLs option.
|
||||
func AppURLs(val map[string]map[string]string) Option {
|
||||
return func(o *Options) {
|
||||
o.AppURLs = val
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware"
|
||||
)
|
||||
|
||||
// NewHandler creates a new grpc service implementing the OpenInApp interface
|
||||
func NewHandler(opts ...Option) (*Service, func(), error) {
|
||||
teardown := func() {}
|
||||
options := newOptions(opts...)
|
||||
@@ -39,7 +40,7 @@ func NewHandler(opts ...Option) (*Service, func(), error) {
|
||||
}, teardown, nil
|
||||
}
|
||||
|
||||
// Service implements the searchServiceHandler interface
|
||||
// Service implements the OpenInApp interface
|
||||
type Service struct {
|
||||
id string
|
||||
appURLs map[string]map[string]string
|
||||
|
||||
Reference in New Issue
Block a user