mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Merge remote-tracking branch 'remotes/origin/develop' into feature/jwt-download-files
# Conflicts: # web/documentserver-example/csharp-mvc/Helpers/DocManagerHelper.cs # web/documentserver-example/csharp-mvc/Models/FileModel.cs # web/documentserver-example/csharp-mvc/WebEditor.ashx.cs # web/documentserver-example/csharp/DocEditor.aspx.cs # web/documentserver-example/csharp/WebEditor.ashx.cs # web/documentserver-example/java/src/main/java/controllers/IndexServlet.java # web/documentserver-example/java/src/main/java/entities/FileModel.java # web/documentserver-example/java/src/main/java/helpers/DocumentManager.java # web/documentserver-example/nodejs/helpers/docManager.js # web/documentserver-example/php/doceditor.php # web/documentserver-example/php/webeditor-ajax.php # web/documentserver-example/python/src/utils/docManager.py # web/documentserver-example/python/src/views/actions.py # web/documentserver-example/ruby/app/controllers/home_controller.rb # web/documentserver-example/ruby/app/models/document_helper.rb # web/documentserver-example/ruby/app/models/file_model.rb
This commit is contained in:
@ -73,18 +73,23 @@ LANGUAGES = {
|
||||
'vi': 'Vietnamese'
|
||||
}
|
||||
|
||||
# check if the file extension can be viewed
|
||||
def isCanView(ext):
|
||||
return ext in config.DOC_SERV_VIEWED
|
||||
|
||||
# check if the file extension can be edited
|
||||
def isCanEdit(ext):
|
||||
return ext in config.DOC_SERV_EDITED
|
||||
|
||||
# check if the file extension can be converted
|
||||
def isCanConvert(ext):
|
||||
return ext in config.DOC_SERV_CONVERT
|
||||
|
||||
# check if the file extension is supported by the editor (it can be viewed or edited or converted)
|
||||
def isSupportedExt(ext):
|
||||
return isCanView(ext) | isCanEdit(ext) | isCanConvert(ext)
|
||||
|
||||
# get internal extension for a given file type
|
||||
def getInternalExtension(fileType):
|
||||
mapping = {
|
||||
'word': '.docx',
|
||||
@ -92,31 +97,35 @@ def getInternalExtension(fileType):
|
||||
'slide': '.pptx'
|
||||
}
|
||||
|
||||
return mapping.get(fileType, '.docx')
|
||||
return mapping.get(fileType, '.docx') # the default file type is .docx
|
||||
|
||||
# get file name with an index if such a file name already exists
|
||||
def getCorrectName(filename, req):
|
||||
basename = fileUtils.getFileNameWithoutExt(filename)
|
||||
ext = fileUtils.getFileExt(filename)
|
||||
name = f'{basename}{ext}'
|
||||
|
||||
i = 1
|
||||
while os.path.exists(getStoragePath(name, req)):
|
||||
name = f'{basename} ({i}){ext}'
|
||||
while os.path.exists(getStoragePath(name, req)): # if file with such a name already exists
|
||||
name = f'{basename} ({i}){ext}' # add an index to its name
|
||||
i += 1
|
||||
|
||||
return name
|
||||
|
||||
# get server url
|
||||
def getServerUrl (forDocumentServer, req):
|
||||
if (forDocumentServer and config.EXAMPLE_DOMAIN is not None):
|
||||
return config.EXAMPLE_DOMAIN
|
||||
else:
|
||||
return req.headers.get("x-forwarded-proto") or req.scheme + "://" + req.get_host()
|
||||
|
||||
# get file url
|
||||
def getFileUri(filename, forDocumentServer, req):
|
||||
host = getServerUrl(forDocumentServer, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}'
|
||||
|
||||
# get absolute URL to the document storage service
|
||||
def getCallbackUrl(filename, req):
|
||||
host = getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
@ -131,6 +140,7 @@ def getDownloadUrl(filename, req):
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}/download?fileName={filename}&userAddress={curAdr}'
|
||||
|
||||
# get root folder for the current file
|
||||
def getRootFolder(req):
|
||||
if isinstance(req, str):
|
||||
curAdr = req
|
||||
@ -139,16 +149,18 @@ def getRootFolder(req):
|
||||
|
||||
directory = os.path.join(config.STORAGE_PATH, curAdr)
|
||||
|
||||
if not os.path.exists(directory):
|
||||
if not os.path.exists(directory): # if such a directory does not exist, make it
|
||||
os.makedirs(directory)
|
||||
|
||||
return directory
|
||||
|
||||
# get the file path
|
||||
def getStoragePath(filename, req):
|
||||
directory = getRootFolder(req)
|
||||
|
||||
return os.path.join(directory, fileUtils.getFileName(filename))
|
||||
|
||||
# get the path to the forcesaved file version
|
||||
def getForcesavePath(filename, req, create):
|
||||
if isinstance(req, str):
|
||||
curAdr = req
|
||||
@ -156,47 +168,50 @@ def getForcesavePath(filename, req, create):
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
|
||||
directory = os.path.join(config.STORAGE_PATH, curAdr)
|
||||
if not os.path.exists(directory):
|
||||
if not os.path.exists(directory): # the directory with host address doesn't exist
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, f'{filename}-hist')
|
||||
directory = os.path.join(directory, f'{filename}-hist') # get the path to the history of the given file
|
||||
if (not os.path.exists(directory)):
|
||||
if create:
|
||||
os.makedirs(directory)
|
||||
else:
|
||||
if create: # if the history directory doesn't exist
|
||||
os.makedirs(directory) # create history directory if it doesn't exist
|
||||
else: # the history directory doesn't exist and we are not supposed to create it
|
||||
return ""
|
||||
|
||||
directory = os.path.join(directory, filename)
|
||||
directory = os.path.join(directory, filename) # and get the path to the given file
|
||||
if (not os.path.exists(directory) and not create):
|
||||
return ""
|
||||
|
||||
return directory
|
||||
|
||||
# get information about all the stored files
|
||||
def getStoredFiles(req):
|
||||
directory = getRootFolder(req)
|
||||
|
||||
files = os.listdir(directory)
|
||||
files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True)
|
||||
files.sort(key=lambda x: os.path.getmtime(os.path.join(directory, x)), reverse=True) # sort files by time of last modification
|
||||
|
||||
fileInfos = []
|
||||
|
||||
for f in files:
|
||||
if os.path.isfile(os.path.join(directory, f)):
|
||||
fileInfos.append({ 'type': fileUtils.getFileType(f), 'title': f, 'url': getFileUri(f, True, req), 'canEdit': isCanEdit(fileUtils.getFileExt(f))})
|
||||
fileInfos.append({ 'type': fileUtils.getFileType(f), 'title': f, 'url': getFileUri(f, True, req), 'canEdit': isCanEdit(fileUtils.getFileExt(f))}) # write information about file type, title and url
|
||||
|
||||
return fileInfos
|
||||
|
||||
# create a file
|
||||
def createFile(stream, path, req = None, meta = False):
|
||||
bufSize = 8192
|
||||
with io.open(path, 'wb') as out:
|
||||
with io.open(path, 'wb') as out: # write data to the file by streams
|
||||
read = stream.read(bufSize)
|
||||
while len(read) > 0:
|
||||
out.write(read)
|
||||
read = stream.read(bufSize)
|
||||
if meta:
|
||||
historyManager.createMeta(path, req)
|
||||
historyManager.createMeta(path, req) # create meta data for the file if needed
|
||||
return
|
||||
|
||||
# create file response
|
||||
def createFileResponse(response, path, req, meta):
|
||||
response.raise_for_status()
|
||||
with open(path, 'wb') as file:
|
||||
@ -204,43 +219,48 @@ def createFileResponse(response, path, req, meta):
|
||||
file.write(chunk)
|
||||
return
|
||||
|
||||
# save file from the given url
|
||||
def saveFileFromUri(uri, path, req = None, meta = False):
|
||||
resp = requests.get(uri, stream=True)
|
||||
createFileResponse(resp, path, req, meta)
|
||||
return
|
||||
|
||||
# create sample file
|
||||
def createSample(fileType, sample, req):
|
||||
ext = getInternalExtension(fileType)
|
||||
ext = getInternalExtension(fileType) # get the internal extension of the given file type
|
||||
|
||||
if not sample:
|
||||
sample = 'false'
|
||||
|
||||
sampleName = 'sample' if sample == 'true' else 'new'
|
||||
sampleName = 'sample' if sample == 'true' else 'new' # create sample or new template
|
||||
|
||||
filename = getCorrectName(f'{sampleName}{ext}', req)
|
||||
filename = getCorrectName(f'{sampleName}{ext}', req) # get file name with an index if such a file name already exists
|
||||
path = getStoragePath(filename, req)
|
||||
|
||||
with io.open(os.path.join('assets', 'sample' if sample == 'true' else 'new', f'{sampleName}{ext}'), 'rb') as stream:
|
||||
with io.open(os.path.join('assets', 'sample' if sample == 'true' else 'new', f'{sampleName}{ext}'), 'rb') as stream: # create sample file of the necessary extension in the directory
|
||||
createFile(stream, path, req, True)
|
||||
return filename
|
||||
|
||||
# remove file from the directory
|
||||
def removeFile(filename, req):
|
||||
path = getStoragePath(filename, req)
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
if os.path.exists(histDir):
|
||||
histDir = historyManager.getHistoryDir(path) # get history directory
|
||||
if os.path.exists(histDir): # remove all the history information about this file
|
||||
shutil.rmtree(histDir)
|
||||
|
||||
# generate file key
|
||||
def generateFileKey(filename, req):
|
||||
path = getStoragePath(filename, req)
|
||||
uri = getFileUri(filename, False, req)
|
||||
stat = os.stat(path)
|
||||
stat = os.stat(path) # get the directory parameters
|
||||
|
||||
h = str(hash(f'{uri}_{stat.st_mtime_ns}'))
|
||||
h = str(hash(f'{uri}_{stat.st_mtime_ns}')) # get the hash value of the file url and the date of its last modification and turn it into a string format
|
||||
replaced = re.sub(r'[^0-9-.a-zA-Z_=]', '_', h)
|
||||
return replaced[:20]
|
||||
return replaced[:20] # take the first 20 characters for the key
|
||||
|
||||
# generate the document key value
|
||||
def generateRevisionId(expectedKey):
|
||||
if (len(expectedKey) > 20):
|
||||
expectedKey = str(hash(expectedKey))
|
||||
@ -248,14 +268,15 @@ def generateRevisionId(expectedKey):
|
||||
key = re.sub(r'[^0-9-.a-zA-Z_=]', '_', expectedKey)
|
||||
return key[:20]
|
||||
|
||||
# get files information
|
||||
def getFilesInfo(req):
|
||||
fileId = req.GET.get('fileId') if req.GET.get('fileId') else None
|
||||
|
||||
result = []
|
||||
resultID = []
|
||||
for f in getStoredFiles(req):
|
||||
stats = os.stat(os.path.join(getRootFolder(req), f.get("title")))
|
||||
result.append(
|
||||
for f in getStoredFiles(req): # run through all the files from the directory
|
||||
stats = os.stat(os.path.join(getRootFolder(req), f.get("title"))) # get file information
|
||||
result.append( # write file parameters to the file object
|
||||
{ "version" : historyManager.getFileVersion(historyManager.getHistoryDir(getStoragePath(f.get("title"), req))),
|
||||
"id" : generateFileKey(f.get("title"), req),
|
||||
"contentLength" : "%.2f KB" % (stats.st_size/1024),
|
||||
@ -263,9 +284,9 @@ def getFilesInfo(req):
|
||||
"title" : f.get("title"),
|
||||
"updated" : time.strftime("%Y-%m-%dT%X%z",time.gmtime(stats.st_mtime))
|
||||
})
|
||||
if fileId :
|
||||
if fileId == generateFileKey(f.get("title"), req) :
|
||||
resultID.append(result[-1])
|
||||
if fileId : # if file id is defined
|
||||
if fileId == generateFileKey(f.get("title"), req) : # and it is equal to the file key value
|
||||
resultID.append(result[-1]) # add file object to the response array
|
||||
|
||||
if fileId :
|
||||
if len(resultID) > 0 : return resultID
|
||||
@ -273,8 +294,9 @@ def getFilesInfo(req):
|
||||
else :
|
||||
return result
|
||||
|
||||
# download the file
|
||||
def download(filePath):
|
||||
response = FileResponse(open(filePath, 'rb'), True)
|
||||
response = FileResponse(open(filePath, 'rb'), True) # write headers to the response object
|
||||
response['Content-Length'] = os.path.getsize(filePath)
|
||||
response['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + urllib.parse.unquote(os.path.basename(filePath))
|
||||
response['Content-Type'] = magic.from_file(filePath, mime=True)
|
||||
|
||||
@ -26,20 +26,24 @@
|
||||
|
||||
import config
|
||||
|
||||
# get file name from the document url
|
||||
def getFileName(str):
|
||||
ind = str.rfind('/')
|
||||
return str[ind+1:]
|
||||
|
||||
# get file name without extension from the document url
|
||||
def getFileNameWithoutExt(str):
|
||||
fn = getFileName(str)
|
||||
ind = fn.rfind('.')
|
||||
return fn[:ind]
|
||||
|
||||
# get file extension from the document url
|
||||
def getFileExt(str):
|
||||
fn = getFileName(str)
|
||||
ind = fn.rfind('.')
|
||||
return fn[ind:].lower()
|
||||
|
||||
# get file type
|
||||
def getFileType(str):
|
||||
ext = getFileExt(str)
|
||||
if ext in config.EXT_DOCUMENT:
|
||||
@ -49,4 +53,4 @@ def getFileType(str):
|
||||
if ext in config.EXT_PRESENTATION:
|
||||
return 'slide'
|
||||
|
||||
return 'word'
|
||||
return 'word' # default file type is word
|
||||
@ -35,57 +35,67 @@ from src import settings
|
||||
from src.utils import docManager
|
||||
from src.utils import jwtManager
|
||||
|
||||
# get the path to the history direction
|
||||
def getHistoryDir(storagePath):
|
||||
return f'{storagePath}-hist'
|
||||
|
||||
# get the path to the given file version
|
||||
def getVersionDir(histDir, version):
|
||||
return os.path.join(histDir, str(version))
|
||||
|
||||
# get file version of the given history directory
|
||||
def getFileVersion(histDir):
|
||||
if not os.path.exists(histDir):
|
||||
return 0
|
||||
if not os.path.exists(histDir): # if the history directory doesn't exist
|
||||
return 0 # file version is 0
|
||||
|
||||
cnt = 1
|
||||
|
||||
for f in os.listdir(histDir):
|
||||
if not os.path.isfile(os.path.join(histDir, f)):
|
||||
for f in os.listdir(histDir): # run through all the files in the history directory
|
||||
if not os.path.isfile(os.path.join(histDir, f)): # and count the number of files
|
||||
cnt += 1
|
||||
|
||||
return cnt
|
||||
|
||||
# get the path to the next file version
|
||||
def getNextVersionDir(histDir):
|
||||
v = getFileVersion(histDir)
|
||||
path = getVersionDir(histDir, v)
|
||||
v = getFileVersion(histDir) # get file version of the given history directory
|
||||
path = getVersionDir(histDir, v) # get the path to the next file version
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
if not os.path.exists(path): # if this path doesn't exist
|
||||
os.makedirs(path) # make the directory for this file version
|
||||
return path
|
||||
|
||||
# get the path to a file archive with differences in the given file version
|
||||
def getChangesZipPath(verDir):
|
||||
return os.path.join(verDir, 'diff.zip')
|
||||
|
||||
# get the path to a json file with changes of the given file version
|
||||
def getChangesHistoryPath(verDir):
|
||||
return os.path.join(verDir, 'changes.json')
|
||||
|
||||
# get the path to the previous file version
|
||||
def getPrevFilePath(verDir, ext):
|
||||
return os.path.join(verDir, f'prev{ext}')
|
||||
|
||||
# get the path to a txt file with a key information in it
|
||||
def getKeyPath(verDir):
|
||||
return os.path.join(verDir, 'key.txt')
|
||||
|
||||
# get the path to a json file with meta data about this file
|
||||
def getMetaPath(histDir):
|
||||
return os.path.join(histDir, 'createdInfo.json')
|
||||
|
||||
# create a json file with file meta data using the storage path and request
|
||||
def createMeta(storagePath, req):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
path = getMetaPath(histDir)
|
||||
path = getMetaPath(histDir) # get the path to a json file with meta data about file
|
||||
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
user = users.getUserFromReq(req)
|
||||
user = users.getUserFromReq(req) # get the user information (id and name)
|
||||
|
||||
obj = {
|
||||
obj = { # create the meta data object
|
||||
'created': datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'uid': user['uid'],
|
||||
'uname': None if user['uid'] == 'uid-0' else user['uname']
|
||||
@ -95,14 +105,15 @@ def createMeta(storagePath, req):
|
||||
|
||||
return
|
||||
|
||||
# create a json file with file meta data using the file name, user id, user name and user address
|
||||
def createMetaData(filename, uid, uname, usAddr):
|
||||
histDir = getHistoryDir(docManager.getStoragePath(filename, usAddr))
|
||||
path = getMetaPath(histDir)
|
||||
path = getMetaPath(histDir) # get the path to a json file with meta data about file
|
||||
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
|
||||
obj = {
|
||||
obj = { # create the meta data object
|
||||
'created': datetime.today().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'uid': uid,
|
||||
'uname': uname
|
||||
@ -112,93 +123,99 @@ def createMetaData(filename, uid, uname, usAddr):
|
||||
|
||||
return
|
||||
|
||||
# create file with a given content in it
|
||||
def writeFile(path, content):
|
||||
with io.open(path, 'w') as out:
|
||||
out.write(content)
|
||||
return
|
||||
|
||||
# read a file
|
||||
def readFile(path):
|
||||
with io.open(path, 'r') as stream:
|
||||
return stream.read()
|
||||
|
||||
# get the url to the previous file version with a given extension
|
||||
def getPrevUri(filename, ver, ext, req):
|
||||
host = docManager.getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}-hist/{ver}/prev{ext}'
|
||||
|
||||
# get the url to a file archive with changes of the given file version
|
||||
def getZipUri(filename, ver, req):
|
||||
host = docManager.getServerUrl(True, req)
|
||||
curAdr = req.META['REMOTE_ADDR']
|
||||
return f'{host}{settings.STATIC_URL}{curAdr}/{filename}-hist/{ver}/diff.zip'
|
||||
|
||||
# get the meta data of the file
|
||||
def getMeta(storagePath):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
path = getMetaPath(histDir)
|
||||
|
||||
if os.path.exists(path):
|
||||
if os.path.exists(path): # check if the json file with file meta data exists
|
||||
with io.open(path, 'r') as stream:
|
||||
return json.loads(stream.read())
|
||||
return json.loads(stream.read()) # turn meta data into python format
|
||||
|
||||
return None
|
||||
|
||||
# get the document history of a given file
|
||||
def getHistoryObject(storagePath, filename, docKey, docUrl, req):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
version = getFileVersion(histDir)
|
||||
if version > 0:
|
||||
if version > 0: # if the file was modified (the file version is greater than 0)
|
||||
hist = []
|
||||
histData = {}
|
||||
|
||||
for i in range(1, version + 1):
|
||||
for i in range(1, version + 1): # run through all the file versions
|
||||
obj = {}
|
||||
dataObj = {}
|
||||
prevVerDir = getVersionDir(histDir, i - 1)
|
||||
verDir = getVersionDir(histDir, i)
|
||||
prevVerDir = getVersionDir(histDir, i - 1) # get the path to the previous file version
|
||||
verDir = getVersionDir(histDir, i) # get the path to the given file version
|
||||
|
||||
try:
|
||||
key = docKey if i == version else readFile(getKeyPath(verDir))
|
||||
key = docKey if i == version else readFile(getKeyPath(verDir)) # get document key
|
||||
|
||||
obj['key'] = key
|
||||
obj['version'] = i
|
||||
dataObj['key'] = key
|
||||
dataObj['version'] = i
|
||||
|
||||
if i == 1:
|
||||
meta = getMeta(storagePath)
|
||||
if meta:
|
||||
if i == 1: # check if the version number is equal to 1
|
||||
meta = getMeta(storagePath) # get meta data of this file
|
||||
if meta: # write meta information to the object (user information and creation date)
|
||||
obj['created'] = meta['created']
|
||||
obj['user'] = {
|
||||
'id': meta['uid'],
|
||||
'name': meta['uname']
|
||||
}
|
||||
|
||||
dataObj['url'] = docUrl if i == version else getPrevUri(filename, i, fileUtils.getFileExt(filename), req)
|
||||
dataObj['url'] = docUrl if i == version else getPrevUri(filename, i, fileUtils.getFileExt(filename), req) # write file url to the data object
|
||||
|
||||
if i > 1:
|
||||
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir)))
|
||||
if i > 1: # check if the version number is greater than 1 (the file was modified)
|
||||
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir))) # get the path to the changes.json file
|
||||
change = changes['changes'][0]
|
||||
|
||||
obj['changes'] = changes['changes']
|
||||
obj['changes'] = changes['changes'] # write information about changes to the object
|
||||
obj['serverVersion'] = changes['serverVersion']
|
||||
obj['created'] = change['created']
|
||||
obj['user'] = change['user']
|
||||
|
||||
prev = histData[str(i - 2)]
|
||||
prevInfo = {
|
||||
prev = histData[str(i - 2)] # get the history data from the previous file version
|
||||
prevInfo = { # write key and url information about previous file version
|
||||
'key': prev['key'],
|
||||
'url': prev['url']
|
||||
}
|
||||
dataObj['previous'] = prevInfo
|
||||
dataObj['changesUrl'] = getZipUri(filename, i - 1, req)
|
||||
dataObj['previous'] = prevInfo # write information about previous file version to the data object
|
||||
dataObj['changesUrl'] = getZipUri(filename, i - 1, req) # write the path to the diff.zip archive with differences in this file version
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
dataObj['token'] = jwtManager.encode(dataObj)
|
||||
|
||||
hist.append(obj)
|
||||
histData[str(i - 1)] = dataObj
|
||||
hist.append(obj) # add object dictionary to the hist list
|
||||
histData[str(i - 1)] = dataObj # write data object information to the history data
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
histObj = {
|
||||
histObj = { # write history information about the current file version to the history object
|
||||
'currentVersion': version,
|
||||
'history': hist
|
||||
}
|
||||
|
||||
@ -27,11 +27,14 @@
|
||||
import config
|
||||
import jwt
|
||||
|
||||
# check if a secret key to generate token exists or not
|
||||
def isEnabled():
|
||||
return bool(config.DOC_SERV_JWT_SECRET)
|
||||
|
||||
# encode a payload object into a token using a secret key and decodes it into the utf-8 format
|
||||
def encode(payload):
|
||||
return jwt.encode(payload, config.DOC_SERV_JWT_SECRET, algorithm='HS256').decode('utf-8')
|
||||
|
||||
# decode a token into a payload object using a secret key
|
||||
def decode(string):
|
||||
return jwt.decode(string, config.DOC_SERV_JWT_SECRET, algorithms=['HS256'])
|
||||
@ -30,13 +30,14 @@ import config
|
||||
|
||||
from . import fileUtils, jwtManager
|
||||
|
||||
# convert file and give url to a new file
|
||||
def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None):
|
||||
if not fromExt:
|
||||
fromExt = fileUtils.getFileExt(docUri)
|
||||
if not fromExt: # check if the extension from the request matches the real file extension
|
||||
fromExt = fileUtils.getFileExt(docUri) # if not, overwrite the extension value
|
||||
|
||||
title = fileUtils.getFileName(docUri)
|
||||
|
||||
payload = {
|
||||
payload = { # write all the necessary data to the payload object
|
||||
'url': docUri,
|
||||
'outputtype': toExt.replace('.', ''),
|
||||
'filetype': fromExt.replace('.', ''),
|
||||
@ -47,20 +48,21 @@ def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None):
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if (isAsync):
|
||||
payload.setdefault('async', True)
|
||||
if (isAsync): # check if the operation is asynchronous
|
||||
payload.setdefault('async', True) # and write this information to the payload object
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
headerToken = jwtManager.encode({'payload': payload})
|
||||
payload['token'] = jwtManager.encode(payload)
|
||||
headers[jwtHeader] = f'Bearer {headerToken}'
|
||||
if jwtManager.isEnabled(): # check if a secret key to generate token exists or not
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER # get jwt header
|
||||
headerToken = jwtManager.encode({'payload': payload}) # encode a payload object into a header token
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers )
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers ) # send the headers and body values to the converter and write the result to the response
|
||||
json = response.json()
|
||||
|
||||
return getResponseUri(json)
|
||||
|
||||
# get response url
|
||||
def getResponseUri(json):
|
||||
isEnd = json.get('endConvert')
|
||||
error = json.get('error')
|
||||
@ -70,6 +72,7 @@ def getResponseUri(json):
|
||||
if isEnd:
|
||||
return json.get('fileUrl')
|
||||
|
||||
# display an error that occurs during conversion
|
||||
def processError(error):
|
||||
prefix = 'Error occurred in the ConvertService: '
|
||||
|
||||
|
||||
@ -31,80 +31,85 @@ import os
|
||||
import json
|
||||
from . import jwtManager, docManager, historyManager, fileUtils, serviceConverter
|
||||
|
||||
# read request body
|
||||
def readBody(request):
|
||||
body = json.loads(request.body)
|
||||
if (jwtManager.isEnabled()):
|
||||
token = body.get('token')
|
||||
if (jwtManager.isEnabled()): # if the secret key to generate token exists
|
||||
token = body.get('token') # get the document token
|
||||
|
||||
if (not token):
|
||||
if (not token): # if JSON web token is not received
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
token = request.headers.get(jwtHeader)
|
||||
token = request.headers.get(jwtHeader) # get it from the Authorization header
|
||||
if token:
|
||||
token = token[len('Bearer '):]
|
||||
token = token[len('Bearer '):] # and save it without Authorization prefix
|
||||
|
||||
if (not token):
|
||||
raise Exception('Expected JWT')
|
||||
if (not token): # if the token is not received
|
||||
raise Exception('Expected JWT') # an error occurs
|
||||
|
||||
body = jwtManager.decode(token)
|
||||
if (body.get('payload')):
|
||||
if (body.get('payload')): # get the payload object from the request body
|
||||
body = body['payload']
|
||||
return body
|
||||
|
||||
# file saving process
|
||||
def processSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
changesUri = body.get('changesurl')
|
||||
newFilename = filename
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
curExt = fileUtils.getFileExt(filename) # get current file extension
|
||||
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
|
||||
|
||||
# convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False) # convert file and give url to a new file
|
||||
if not newUri:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr) # get the correct file name if it already exists
|
||||
else:
|
||||
download = newUri
|
||||
except Exception:
|
||||
newFilename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + downloadExt, usAddr)
|
||||
|
||||
path = docManager.getStoragePath(newFilename, usAddr)
|
||||
path = docManager.getStoragePath(newFilename, usAddr) # get the file path
|
||||
|
||||
histDir = historyManager.getHistoryDir(path)
|
||||
if not os.path.exists(histDir):
|
||||
os.makedirs(histDir)
|
||||
histDir = historyManager.getHistoryDir(path) # get the path to the history direction
|
||||
if not os.path.exists(histDir): # if the path doesn't exist
|
||||
os.makedirs(histDir) # create it
|
||||
|
||||
versionDir = historyManager.getNextVersionDir(histDir)
|
||||
versionDir = historyManager.getNextVersionDir(histDir) # get the path to the next file version
|
||||
|
||||
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt))
|
||||
docManager.saveFileFromUri(download, path)
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir))
|
||||
os.rename(docManager.getStoragePath(filename, usAddr), historyManager.getPrevFilePath(versionDir, curExt)) # get the path to the previous file version and rename the storage path with it
|
||||
docManager.saveFileFromUri(download, path) # save file to the storage path
|
||||
docManager.saveFileFromUri(changesUri, historyManager.getChangesZipPath(versionDir)) # save file changes to the diff.zip archive
|
||||
|
||||
hist = None
|
||||
hist = body.get('changeshistory')
|
||||
if (not hist) & ('history' in body):
|
||||
hist = json.dumps(body.get('history'))
|
||||
if hist:
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist)
|
||||
historyManager.writeFile(historyManager.getChangesHistoryPath(versionDir), hist) # write the history changes to the changes.json file
|
||||
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key'))
|
||||
historyManager.writeFile(historyManager.getKeyPath(versionDir), body.get('key')) # write the key value to the key.txt file
|
||||
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False)
|
||||
if (forcesavePath != ""):
|
||||
os.remove(forcesavePath)
|
||||
forcesavePath = docManager.getForcesavePath(newFilename, usAddr, False) # get the path to the forcesaved file version
|
||||
if (forcesavePath != ""): # if the forcesaved file version exists
|
||||
os.remove(forcesavePath) # remove it
|
||||
|
||||
return
|
||||
|
||||
# file force saving process
|
||||
def processForceSave(body, filename, usAddr):
|
||||
download = body.get('url')
|
||||
|
||||
curExt = fileUtils.getFileExt(filename)
|
||||
downloadExt = fileUtils.getFileExt(download)
|
||||
curExt = fileUtils.getFileExt(filename) # get current file extension
|
||||
downloadExt = fileUtils.getFileExt(download) # get the extension of the downloaded file
|
||||
newFilename = False
|
||||
|
||||
# convert downloaded file to the file with the current extension if these extensions aren't equal
|
||||
if (curExt != downloadExt):
|
||||
try:
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False)
|
||||
newUri = serviceConverter.getConverterUri(download, downloadExt, curExt, docManager.generateRevisionId(download), False) # convert file and give url to a new file
|
||||
if not newUri:
|
||||
newFilename = True
|
||||
else:
|
||||
@ -112,11 +117,11 @@ def processForceSave(body, filename, usAddr):
|
||||
except Exception:
|
||||
newFilename = True
|
||||
|
||||
isSubmitForm = body.get('forcesavetype') == 3
|
||||
isSubmitForm = body.get('forcesavetype') == 3 # SubmitForm
|
||||
|
||||
if(isSubmitForm):
|
||||
if (newFilename):
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + downloadExt, usAddr)
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + downloadExt, usAddr) # get the correct file name if it already exists
|
||||
else :
|
||||
filename = docManager.getCorrectName(fileUtils.getFileNameWithoutExt(filename) + "-form" + curExt, usAddr)
|
||||
forcesavePath = docManager.getStoragePath(filename, usAddr)
|
||||
@ -130,10 +135,11 @@ def processForceSave(body, filename, usAddr):
|
||||
docManager.saveFileFromUri(download, forcesavePath)
|
||||
|
||||
if(isSubmitForm):
|
||||
uid = body['actions'][0]['userid']
|
||||
historyManager.createMetaData(filename, uid, "Filling Form", usAddr)
|
||||
uid = body['actions'][0]['userid'] # get the user id
|
||||
historyManager.createMetaData(filename, uid, "Filling Form", usAddr) # create meta data for forcesaved file
|
||||
return
|
||||
|
||||
# create a command request
|
||||
def commandRequest(method, key):
|
||||
documentCommandUrl = config.DOC_SERV_SITE_URL + config.DOC_SERV_COMMAND_URL
|
||||
|
||||
@ -144,12 +150,12 @@ def commandRequest(method, key):
|
||||
|
||||
headers={'accept': 'application/json'}
|
||||
|
||||
if jwtManager.isEnabled():
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER
|
||||
headerToken = jwtManager.encode({'payload': payload})
|
||||
headers[jwtHeader] = f'Bearer {headerToken}'
|
||||
if jwtManager.isEnabled(): # check if a secret key to generate token exists or not
|
||||
jwtHeader = 'Authorization' if config.DOC_SERV_JWT_HEADER is None or config.DOC_SERV_JWT_HEADER == '' else config.DOC_SERV_JWT_HEADER # get jwt header
|
||||
headerToken = jwtManager.encode({'payload': payload}) # encode a payload object into a header token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
payload['token'] = jwtManager.encode(payload)
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
|
||||
response = requests.post(documentCommandUrl, json=payload, headers=headers)
|
||||
|
||||
|
||||
@ -47,11 +47,12 @@ USERS = [
|
||||
|
||||
DEFAULT_USER = USERS[0]
|
||||
|
||||
# get user information from the request
|
||||
def getUserFromReq(req):
|
||||
uid = req.COOKIES.get('uid')
|
||||
uname = req.COOKIES.get('uname')
|
||||
|
||||
if (not uid) | (not uname):
|
||||
return DEFAULT_USER
|
||||
if (not uid) | (not uname): # check if we got both the user id and name parameters
|
||||
return DEFAULT_USER # if not, return default user values
|
||||
else:
|
||||
return { 'uid': unquote(uid), 'uname': unquote(uname) }
|
||||
Reference in New Issue
Block a user