Skip to content

Commit 6f31fd6

Browse files
committed
Refactoring of the GORM model for shares
1 parent f41ee18 commit 6f31fd6

File tree

3 files changed

+129
-159
lines changed

3 files changed

+129
-159
lines changed

pkg/share/manager/sql/conversions.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,35 @@ import (
3232
model "github.com/cs3org/reva/v3/pkg/share/manager/sql/model"
3333
)
3434

35-
func convertFromCS3OCMShareType(shareType ocm.ShareType) model.ShareType {
35+
func convertFromCS3OCMShareType(shareType ocm.ShareType) model.OcmShareType {
3636
switch shareType {
3737
case ocm.ShareType_SHARE_TYPE_USER:
38-
return model.ShareTypeUser
38+
return model.OcmShareTypeUser
3939
case ocm.ShareType_SHARE_TYPE_GROUP:
40-
return model.ShareTypeGroup
40+
return model.OcmShareTypeGroup
4141
}
4242
return -1
4343
}
4444

4545
func convertFromCS3OCMShareState(shareState ocm.ShareState) model.OcmShareState {
4646
switch shareState {
4747
case ocm.ShareState_SHARE_STATE_ACCEPTED:
48-
return model.ShareStateAccepted
48+
return model.OcmShareStateAccepted
4949
case ocm.ShareState_SHARE_STATE_PENDING:
50-
return model.ShareStatePending
50+
return model.OcmShareStatePending
5151
case ocm.ShareState_SHARE_STATE_REJECTED:
52-
return model.ShareStateRejected
52+
return model.OcmShareStateRejected
5353
}
5454
return -1
5555
}
5656

5757
func convertToCS3OCMShareState(state model.OcmShareState) ocm.ShareState {
5858
switch state {
59-
case model.ShareStateAccepted:
59+
case model.OcmShareStateAccepted:
6060
return ocm.ShareState_SHARE_STATE_ACCEPTED
61-
case model.ShareStatePending:
61+
case model.OcmShareStatePending:
6262
return ocm.ShareState_SHARE_STATE_PENDING
63-
case model.ShareStateRejected:
63+
case model.OcmShareStateRejected:
6464
return ocm.ShareState_SHARE_STATE_REJECTED
6565
}
6666
return ocm.ShareState_SHARE_STATE_INVALID
@@ -73,8 +73,8 @@ func convertToCS3OCMShare(s *model.OcmShare, am []*ocm.AccessMethod) *ocm.Share
7373
OpaqueId: strconv.Itoa(int(s.Id)),
7474
},
7575
ResourceId: &provider.ResourceId{
76-
StorageId: s.FileidPrefix,
77-
OpaqueId: s.ItemSource,
76+
StorageId: s.StorageId,
77+
OpaqueId: s.FileId,
7878
},
7979
Name: s.Name,
8080
Token: s.Token,
@@ -161,15 +161,15 @@ func viewModeToInt(v appprovider.ViewMode) int {
161161
return -1
162162
}
163163

164-
func convertToCS3AccessMethod(m *model.OcmSharesAccessMethod) *ocm.AccessMethod {
164+
func convertToCS3AccessMethod(m *model.OcmShareProtocol) *ocm.AccessMethod {
165165
switch m.Type {
166-
case model.WebDAVAccessMethod:
166+
case model.WebDAVProtocol:
167167
return share.NewWebDavAccessMethod(
168168
conversions.RoleFromOCSPermissions(conversions.Permissions(m.Permissions)).CS3ResourcePermissions(),
169169
[]string{}) // TODO persist requirements
170-
case model.WebappAccessMethod:
170+
case model.WebappProtocol:
171171
return share.NewWebappAccessMethod(appprovider.ViewMode(m.Permissions))
172-
case model.TransferAccessMethod:
172+
case model.TransferProtocol:
173173
return share.NewTransferAccessMethod()
174174
}
175175
return nil
@@ -189,22 +189,22 @@ func convertToCS3Protocol(p *model.OcmReceivedShareProtocol) *ocm.Protocol {
189189
return nil
190190
}
191191

192-
func convertToCS3ResourceType(t model.OcmItemType) provider.ResourceType {
192+
func convertToCS3ResourceType(t model.ItemType) provider.ResourceType {
193193
switch t {
194-
case model.OcmItemTypeFile:
194+
case model.ItemTypeFile:
195195
return provider.ResourceType_RESOURCE_TYPE_FILE
196-
case model.OcmItemTypeFolder:
196+
case model.ItemTypeFolder:
197197
return provider.ResourceType_RESOURCE_TYPE_CONTAINER
198198
}
199199
return provider.ResourceType_RESOURCE_TYPE_INVALID
200200
}
201201

202-
func convertFromCS3ResourceType(t provider.ResourceType) model.OcmItemType {
202+
func convertFromCS3ResourceType(t provider.ResourceType) model.ItemType {
203203
switch t {
204204
case provider.ResourceType_RESOURCE_TYPE_FILE:
205-
return model.OcmItemTypeFile
205+
return model.ItemTypeFile
206206
case provider.ResourceType_RESOURCE_TYPE_CONTAINER:
207-
return model.OcmItemTypeFolder
207+
return model.ItemTypeFolder
208208
}
209-
return -1
209+
return model.ItemTypeFile
210210
}

pkg/share/manager/sql/model/model.go

Lines changed: 77 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -36,124 +36,104 @@ import (
3636
"gorm.io/gorm"
3737
)
3838

39-
// AccessMethod is method granted by the sharer to access
40-
// the shared resource.
41-
type AccessMethod int
39+
// ItemType is the type of the shared resource.
40+
type ItemType string
4241

4342
const (
44-
// WebDAVAccessMethod indicates an access using WebDAV to the share.
45-
WebDAVAccessMethod AccessMethod = iota
46-
// WebappAccessMethod indicates an access using a collaborative
47-
// application to the share.
48-
WebappAccessMethod
49-
// TransferAccessMethod indicates a share for a transfer.
50-
TransferAccessMethod
43+
ItemTypeFile ItemType = "file"
44+
ItemTypeFolder ItemType = "folder"
45+
ItemTypeReference ItemType = "reference"
46+
ItemTypeSymlink ItemType = "symlink"
5147
)
5248

53-
// ShareState is the state of the share.
54-
type OcmShareState int
55-
56-
const (
57-
// ShareTypeUser is used for a share to an user.
58-
ShareTypeUser ShareType = iota
59-
// ShareTypeGroup is used for a share to a group.
60-
ShareTypeGroup
61-
)
49+
func (i ItemType) String() string {
50+
return string(i)
51+
}
6252

63-
// ShareType is the type of the share.
64-
type ShareType int
53+
// For OCM shares, OcmShareType is the type of the recipient.
54+
type OcmShareType int
6555

6656
const (
67-
// ShareStatePending is the state for a pending share.
68-
ShareStatePending OcmShareState = iota
69-
// ShareStateAccepted is the share for an accepted share.
70-
ShareStateAccepted
71-
// ShareStateRejected is the share for a rejected share.
72-
ShareStateRejected
57+
// OcmShareTypeUser is used for a share to an user.
58+
OcmShareTypeUser OcmShareType = iota
59+
// OcmShareTypeGroup is used for a share to a group.
60+
OcmShareTypeGroup
7361
)
7462

75-
// ItemType is the type of the shares resource.
76-
type OcmItemType int
63+
// For OCM shares, OcmShareState is their state.
64+
type OcmShareState int
7765

7866
const (
79-
// ItemTypeFile is used when the shared resource is a file.
80-
OcmItemTypeFile OcmItemType = iota
81-
// ItemTypeFolder is used when the shared resource is a folder.
82-
OcmItemTypeFolder
67+
// OcmShareStatePending is the state for a pending share.
68+
OcmShareStatePending OcmShareState = iota
69+
// OcmShareStateAccepted is the share for an accepted share.
70+
OcmShareStateAccepted
71+
// OcmShareStateRejected is the share for a rejected share.
72+
OcmShareStateRejected
8373
)
8474

85-
// Protocol is the protocol the recipient of the share
86-
// uses to access the shared resource.
87-
type Protocol int
75+
// OcmProtocol is the protocol used by the recipient of an OCM share
76+
// (both incoming and outgoing) to access the shared resource.
77+
type OcmProtocol int
8878

8979
const (
90-
// WebDAVProtocol is the WebDav protocol.
91-
WebDAVProtocol Protocol = iota
92-
// WebappProtocol is the Webapp protocol.
80+
// WebDAVProtocol is the OCM `webdav` protocol.
81+
WebDAVProtocol OcmProtocol = iota
82+
// WebappProtocol is the OCM `webapp` protocol.
9383
WebappProtocol
94-
// TransferProtocol is the Transfer protocol.
84+
// TransferProtocol is the OCM `datatx` protocol.
9585
TransferProtocol
9686
)
9787

98-
type ItemType string
99-
100-
const (
101-
ItemTypeFile ItemType = "file"
102-
ItemTypeFolder ItemType = "folder"
103-
ItemTypeReference ItemType = "reference"
104-
ItemTypeSymlink ItemType = "symlink"
105-
)
106-
107-
func (i ItemType) String() string {
108-
return string(i)
109-
}
110-
11188
// ShareID only contains IDs of shares and public links. This is because the Web UI requires
11289
// that shares and public links do not share an ID, so we need a shared table to make sure
11390
// that there are no duplicates.
11491
// This is implemented by having ShareID have an ID that is auto-increment, and shares and
11592
// public links will have their ID be a foreign key to ShareID
11693
// When creating a new share, we will then first create an ID entry and use this for the ID
117-
11894
type ShareID struct {
11995
ID uint `gorm:"primarykey"`
12096
}
12197

122-
// We cannot use gorm.Model, because we want our ID to be a foreign key to ShareID
98+
// This is the base model for all share types. We cannot use gorm.Model, because we want our ID
99+
// to be a foreign key to ShareID, but we incorporate the date fields from gorm.
100+
// The DeletedAt field is included in multiple unique indexes to allow soft deletion while
101+
// maintaining uniqueness constraints.
123102
type BaseModel struct {
124103
// Id has to be called Id and not ID, otherwise the foreign key will not work
125104
// ID is a special field in GORM, which it uses as the default Primary Key
126105
Id uint `gorm:"primaryKey;not null;autoIncrement:false"`
127106
ShareId ShareID `gorm:"foreignKey:Id;references:ID;constraint:OnDelete:CASCADE"` //;references:ID
128107
CreatedAt time.Time
129108
UpdatedAt time.Time
130-
DeletedAt gorm.DeletedAt `gorm:"index"`
109+
DeletedAt gorm.DeletedAt `gorm:"uniqueIndex:u_share;uniqueIndex:u_link;uniqueIndex:u_ocmshare"`
131110
}
132111

133-
// ProtoShare contains fields that are shared between PublicLinks and Shares.
134-
// Unfortunately, because these are shared, we cannot name our indexes
135-
// because then two indexes with the same name would be created
112+
// ProtoShare contains fields that are common between PublicLinks and Shares.
136113
type ProtoShare struct {
137-
// Including gorm.Model will embed a number of gorm-default fields
138114
BaseModel
139115
UIDOwner string `gorm:"size:64"`
140-
UIDInitiator string `gorm:"size:64;index"`
116+
UIDInitiator string `gorm:"size:64;uniqueIndex:u_share;uniqueIndex:u_link"`
141117
ItemType ItemType `gorm:"size:16;index"` // file | folder | reference | symlink
142118
InitialPath string
143-
Inode string `gorm:"size:32;index"`
144-
Instance string `gorm:"size:32;index"`
145-
Permissions uint8
119+
Inode string `gorm:"size:32;uniqueIndex:u_share;uniqueIndex:u_link"`
120+
Instance string `gorm:"size:32;uniqueIndex:u_share;uniqueIndex:u_link"`
121+
Permissions uint8 `gorm:"uniqueIndex:u_share;uniqueIndex:u_link"`
146122
Orphan bool
147123
Expiration datatypes.NullTime
148124
}
149125

126+
// Share is a regular share between users or groups. The unique index ensures that there
127+
// can only be one share per (initiator, inode, instance, permissions, recipient) tuple, unless the share is deleted.
150128
type Share struct {
151129
ProtoShare
152-
ShareWith string `gorm:"size:255;index:i_share_with"` // 255 because this can be a lw account, which are mapped from email addresses / ...
130+
ShareWith string `gorm:"size:255;uniqueIndex:u_share"` // 255 because this can be an external account, which has a long representation
153131
SharedWithIsGroup bool
154132
Description string `gorm:"size:1024"`
155133
}
156134

135+
// PublicLink is a public link share. The unique index ensures that there
136+
// can only be one public link per (initiator, inode, instance, permissions) tuple, unless the link is deleted.
157137
type PublicLink struct {
158138
ProtoShare
159139
// Current tokens are only 16 chars long, but old tokens used to be 32 characters
@@ -162,10 +142,10 @@ type PublicLink struct {
162142
NotifyUploads bool
163143
NotifyUploadsExtraRecipients string
164144
Password string `gorm:"size:255"`
165-
// Users can give a name to a share
166-
LinkName string `gorm:"size:512"`
145+
LinkName string `gorm:"size:512"` // Users can give a name to a share
167146
}
168147

148+
// ShareState represents the state of a share for a specific recipient.
169149
type ShareState struct {
170150
gorm.Model
171151
ShareID uint `gorm:"uniqueIndex:i_shareid_user"` // Define the foreign key field
@@ -177,64 +157,54 @@ type ShareState struct {
177157
Alias string `gorm:"size:64"`
178158
}
179159

160+
// OcmShare represents an OCM share for a remote user. The unique index ensures that there
161+
// can only be one share per (storageId, fileId, shareWith, owner) tuple, unless the share is deleted.
180162
type OcmShare struct {
181-
// The fields of the base model had to be copied since we need an index on DeletedAt + unique constraints
182-
// Id has to be called Id and not ID, otherwise the foreign key will not work
183-
// ID is a special field in GORM, which it uses as the default Primary Key
184-
Id uint `gorm:"primaryKey;not null;autoIncrement:false"`
185-
ShareId ShareID `gorm:"foreignKey:Id;references:ID;constraint:OnDelete:CASCADE"`
186-
CreatedAt time.Time
187-
UpdatedAt time.Time
188-
// Needs to be indexed because shares that are deleted need to be unique so we can add a new share after it was deleted
189-
DeletedAt gorm.DeletedAt `gorm:"index;uniqueIndex:idx_fileid_source_share_with_deletedat"`
190-
Token string `gorm:"size:255;not null;uniqueIndex"`
191-
FileidPrefix string `gorm:"size:64;not null;uniqueIndex:idx_fileid_source_share_with_deletedat"`
192-
ItemSource string `gorm:"size:64;not null;uniqueIndex:idx_fileid_source_share_with_deletedat"`
193-
Name string `gorm:"type:text;not null"`
194-
ShareWith string `gorm:"size:255;not null;uniqueIndex:idx_fileid_source_share_with_deletedat"`
195-
Owner string `gorm:"size:255;not null;uniqueIndex:idx_fileid_source_share_with_deletedat"`
196-
Initiator string `gorm:"type:text;not null"`
197-
Ctime uint64 `gorm:"not null"`
198-
Mtime uint64 `gorm:"not null"`
199-
Expiration sql.NullInt64 `gorm:"default:null"`
200-
Type ShareType `gorm:"not null"`
201-
AccessMethods []OcmSharesAccessMethod `gorm:"constraint:OnDelete:CASCADE;"`
163+
BaseModel
164+
Token string `gorm:"size:255;not null;uniqueIndex:i_ocmshare_token"`
165+
StorageId string `gorm:"size:64;not null;uniqueIndex:u_ocmshare"`
166+
FileId string `gorm:"size:64;not null;uniqueIndex:u_ocmshare"`
167+
Name string `gorm:"type:text;not null"`
168+
ShareWith string `gorm:"size:255;not null;uniqueIndex:u_ocmshare"`
169+
Owner string `gorm:"size:255;not null;uniqueIndex:u_ocmshare"`
170+
Initiator string `gorm:"type:text;not null"`
171+
Ctime uint64 `gorm:"not null"`
172+
Mtime uint64 `gorm:"not null"`
173+
Expiration sql.NullInt64 `gorm:"default:null"`
174+
Type OcmShareType `gorm:"not null"`
175+
Protocols []OcmShareProtocol `gorm:"constraint:OnDelete:CASCADE;"`
202176
}
203177

204-
// OCM Shares Access Methods
205-
type OcmSharesAccessMethod struct {
178+
// OcmShareProtocol represents the protocol used to access an OCM share, named AccessMethod in the OCM CS3 APIs.
179+
type OcmShareProtocol struct {
206180
gorm.Model
207-
OcmShareID uint `gorm:"not null;uniqueIndex:idx_ocm_share_method"`
208-
//OcmShare OcmShare `gorm:"constraint:OnDelete:CASCADE;foreignKey:OcmShareID;references:Id"`
209-
Type AccessMethod `gorm:"not null;uniqueIndex:idx_ocm_share_method"`
210-
// WebDAV and WebApp fields
211-
Permissions int `gorm:"default:null"`
181+
OcmShareID uint `gorm:"not null;uniqueIndex:u_ocm_share_protocol"`
182+
Type OcmProtocol `gorm:"not null;uniqueIndex:u_ocm_share_protocol"`
183+
Permissions int `gorm:"default:null"`
212184
}
213185

214-
// OCM Received Shares
186+
// OcmReceivedShare represents an OCM share received from a remote user.
215187
type OcmReceivedShare struct {
216188
gorm.Model
217-
RemoteShareID string `gorm:"not null"`
189+
RemoteShareID string `gorm:"index:i_ocmrecshare_remoteshareid;not null"`
218190
Name string `gorm:"size:255;not null"`
219-
FileidPrefix string `gorm:"size:255;not null"`
220-
ItemSource string `gorm:"size:255;not null"`
221-
ItemType OcmItemType `gorm:"not null"`
191+
ItemType ItemType `gorm:"size:16;not null"`
222192
ShareWith string `gorm:"size:255;not null"`
223-
Owner string `gorm:"size:255;not null"`
224-
Initiator string `gorm:"size:255;not null"`
193+
Owner string `gorm:"index:i_ocmrecshare_owner;size:255;not null"`
194+
Initiator string `gorm:"index:i_ocmrecshare_initiator;size:255;not null"`
225195
Ctime uint64 `gorm:"not null"`
226196
Mtime uint64 `gorm:"not null"`
227197
Expiration sql.NullInt64 `gorm:"default:null"`
228-
Type ShareType `gorm:"not null"`
229-
State OcmShareState `gorm:"not null"`
198+
Type OcmShareType `gorm:"index:i_ocmrecshare_type;not null"`
199+
State OcmShareState `gorm:"index:i_ocmrecshare_state;not null"`
230200
}
231201

232-
// OCM Received Share Protocols
202+
// OcmReceivedShareProtocol represents the protocol used to access an OCM share received from a remote user.
233203
type OcmReceivedShareProtocol struct {
234204
gorm.Model
235-
OcmReceivedShareID uint `gorm:"not null;uniqueIndex:idx_received_share_protocol"`
205+
OcmReceivedShareID uint `gorm:"not null;uniqueIndex:u_ocmrecshare_protocol"`
236206
OcmReceivedShare OcmReceivedShare `gorm:"constraint:OnDelete:CASCADE;foreignKey:OcmReceivedShareID;references:ID"`
237-
Type Protocol `gorm:"not null;uniqueIndex:idx_received_share_protocol"`
207+
Type OcmProtocol `gorm:"not null;uniqueIndex:u_ocmrecshare_protocol"`
238208
Uri string `gorm:"size:255"`
239209
SharedSecret string `gorm:"type:text;not null"`
240210
// WebDAV and WebApp Protocol fields

0 commit comments

Comments
 (0)