Skip to content

Commit 364254e

Browse files
committed
Make the new CheckFileInfo properties only wopivalidator-specific
1 parent a1b106b commit 364254e

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

src/core/wopi.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def checkFileInfo(fileid, acctok):
3535
acctok['usertype'] = utils.UserType(acctok['usertype'])
3636
statInfo = st.statx(acctok['endpoint'], acctok['filename'], acctok['userid'])
3737

38-
# populate metadata for this file
38+
# ** Populate general metadata for this file **
3939
fmd = {}
4040
fmd['BaseFileName'] = fmd['BreadcrumbDocName'] = os.path.basename(acctok['filename'])
4141
fmd['FileExtension'] = os.path.splitext(acctok['filename'])[1]
@@ -72,9 +72,6 @@ def checkFileInfo(fileid, acctok):
7272
if acctok['viewmode'] != utils.ViewMode.VIEW_ONLY and srv.config.get('general', 'downloadurl', fallback=None):
7373
fmd['DownloadUrl'] = fmd['FileUrl'] = '%s?access_token=%s' % \
7474
(srv.config.get('general', 'downloadurl'), flask.request.args['access_token'])
75-
if srv.config.get('apps', 'businessflow', fallback='True').upper() == 'TRUE':
76-
# according to Microsoft, this must be enabled for all users
77-
fmd['LicenseCheckForEditIsEnabled'] = True
7875
fmd['BreadcrumbBrandName'] = srv.config.get('general', 'brandingname', fallback=None)
7976
fmd['BreadcrumbBrandUrl'] = srv.config.get('general', 'brandingurl', fallback=None)
8077
fmd['OwnerId'] = statInfo['ownerid']
@@ -83,6 +80,9 @@ def checkFileInfo(fileid, acctok):
8380
fmd['LastModifiedTime'] = str(datetime.fromtimestamp(int(statInfo['mtime']))) + '.000'
8481
# note that in ownCloud 10 the version is generated as: `'V' + etag + checksum`. Here etag is `version:checksum`.
8582
fmd['Version'] = f"v{statInfo['etag']}"
83+
fmd['AccessTokenExpiry'] = acctok['exp'] * 1000
84+
fmd['ServerTime'] = int(time.time()) * 1000
85+
8686
fmd['SupportsExtendedLockLength'] = fmd['SupportsGetLock'] = fmd['SupportsCoauth'] = True
8787
fmd['SupportsUpdate'] = fmd['UserCanWrite'] = fmd['SupportsLocks'] = \
8888
fmd['SupportsDeleteFile'] = acctok['viewmode'] in (utils.ViewMode.READ_WRITE, utils.ViewMode.PREVIEW)
@@ -96,47 +96,55 @@ def checkFileInfo(fileid, acctok):
9696
acctok['usertype'] != utils.UserType.REGULAR
9797
fmd['SupportsRename'] = fmd['UserCanRename'] = enablerename and \
9898
acctok['viewmode'] in (utils.ViewMode.READ_WRITE, utils.ViewMode.PREVIEW)
99-
fmd['AccessTokenExpiry'] = acctok['exp'] * 1000
100-
fmd['FileGeoLocationCode'] = fmd['RealTimeChannelEndpointUrl'] = \
101-
fmd['OfficeCollaborationServiceEndpointUrl'] = '' # to please the wopi validator
102-
fmd['SharingStatus'] = 'Shared'
103-
fmd['ServerTime'] = int(time.time()) * 1000
104-
try:
105-
fmd['SequenceNumber'] = int(statInfo['etag'][:statInfo['etag'].find(':')])
106-
except (ValueError, AttributeError):
107-
log.warning('msg="Failed to extract SequenceNumber from etag" ' +
108-
f'token="{flask.request.args["access_token"][-20:]}" etag="{statInfo["etag"]}"')
10999
fmd['SupportsUserInfo'] = True
110100
uinfo = statInfo['xattrs'].get(utils.USERINFOKEY + '.' + acctok['wopiuser'].split('!')[0])
111101
if uinfo:
112102
fmd['UserInfo'] = uinfo
113103

114-
# populate app-specific metadata
104+
# ** Populate app-specific metadata **
105+
if srv.config.get('apps', 'businessflow', fallback='True').upper() == 'TRUE':
106+
# according to Microsoft, this must be enabled for all users
107+
fmd['LicenseCheckForEditIsEnabled'] = True
115108
if srv.config.get('apps', 'earlyfeatures', fallback='False').upper() == 'TRUE':
116109
fmd['AllowEarlyFeatures'] = True
117110
if srv.config.has_option('apps', 'compliancedomain'):
118111
fmd['ComplianceDomainPrefix'] = srv.config.get('apps', 'compliancedomain')
112+
113+
# 28/11/2025: the following properties are CSPP+ related and necessary only when running the wopivalidator,
114+
# with 'SequenceNumber' even breaking normal CSPP Office apps:
115+
# learn.microsoft.com/en-us/microsoft-365/cloud-storage-partner-program/rest/files/checkfileinfo/checkfileinfo-csppp
116+
if '.wopitest' in fmd['BaseFileName']:
117+
fmd['SharingStatus'] = 'Shared'
118+
fmd['FileGeoLocationCode'] = srv.config.get('apps', 'compliancedomain', fallback='euc')
119+
fmd['RealTimeChannelEndpointUrl'] = fmd['OfficeCollaborationServiceEndpointUrl'] = ''
120+
try:
121+
fmd['SequenceNumber'] = int(statInfo['etag'][:statInfo['etag'].find(':')])
122+
except (ValueError, AttributeError):
123+
log.warning('msg="Failed to extract SequenceNumber from etag" ' +
124+
f'token="{flask.request.args["access_token"][-20:]}" etag="{statInfo["etag"]}"')
125+
119126
# the following is to enable the 'Edit in Word/Excel/PowerPoint' (desktop) action (probably broken)
120127
try:
121128
fmd['ClientUrl'] = srv.config.get('general', 'webdavurl') + '/' + acctok['filename']
122129
except configparser.NoOptionError:
123130
# if no WebDAV URL is provided, ignore this setting
124131
pass
132+
125133
# extensions for Collabora Online
126134
if 'Collabora' in acctok['appname']:
127135
fmd['EnableOwnerTermination'] = True
128136
fmd['DisableExport'] = fmd['DisableCopy'] = fmd['DisablePrint'] = acctok['viewmode'] == utils.ViewMode.VIEW_ONLY
129137
if srv.config.get('apps', 'codedisableexport', fallback='False').upper() == 'TRUE':
130138
fmd['UserCanNotWriteRelative'] = fmd['DisableExport'] = True
131139

140+
# ** Response and log **
132141
res = flask.Response(json.dumps(fmd), mimetype='application/json')
133-
134-
# redact sensitive metadata for the logs
135142
if srv.config.get('general', 'loglevel') != 'Debug':
136143
fmd['HostViewUrl'] = fmd['HostEditUrl'] = fmd['DownloadUrl'] = fmd['FileUrl'] = \
137144
fmd['BreadcrumbBrandUrl'] = fmd['FileSharingUrl'] = '_redacted_'
138145
log.info(f"msg=\"File metadata response\" token=\"{flask.request.args['access_token'][-20:]}\" metadata=\"{fmd}\"")
139146
return res
147+
140148
except IOError as e:
141149
log.info('msg="Requested file not found" filename="%s" token="%s" details="%s"' %
142150
(acctok['filename'], flask.request.args['access_token'][-20:], e))

0 commit comments

Comments
 (0)