Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/hub/blobs.coffee
1496 views
1
#########################################################################
2
# This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
# License: MS-RSL – see LICENSE.md for details
4
#########################################################################
5
6
# Blobs
7
8
winston = require('./logger').getLogger('blobs')
9
10
misc_node = require('@cocalc/backend/misc_node')
11
misc = require('@cocalc/util/misc')
12
{defaults, required} = misc
13
{MAX_BLOB_SIZE} = require('@cocalc/util/db-schema/blobs')
14
15
# save a blob in the blobstore database with given misc_node.uuidsha1 hash.
16
exports.save_blob = (opts) ->
17
opts = defaults opts,
18
uuid : undefined # uuid=sha1-based from blob; actually *required*, but instead of a traceback, get opts.cb(err)
19
blob : undefined # actually *required*, but instead of a traceback, get opts.cb(err)
20
ttl : undefined # object in blobstore will have *at least* this ttl in seconds;
21
# if there is already something, in blobstore with longer ttl, we leave it; undefined = infinite ttl
22
check : true # if true, return an error (via cb) if misc_node.uuidsha1(opts.blob) != opts.uuid.
23
# This is a check against bad user-supplied data.
24
project_id : undefined
25
account_id : undefined
26
database : required
27
cb : required # cb(err, ttl actually used in seconds); ttl=0 for infinite ttl
28
29
dbg = (m) -> winston.debug("save_blob(uuid=#{opts.uuid}): #{m}")
30
dbg()
31
32
err = undefined
33
34
if not opts.blob?
35
err = "save_blob: UG -- error in call to save_blob (uuid=#{opts.uuid}); received a save_blob request with undefined blob"
36
37
else if not opts.uuid?
38
err = "save_blob: BUG -- error in call to save_blob; received a save_blob request without corresponding uuid"
39
40
else if not opts.project_id?
41
err = "save_blob: BUG -- error in call to save_blob; received a save_blob request without corresponding project_id"
42
43
else if opts.blob.length > MAX_BLOB_SIZE
44
err = "save_blob: blobs are limited to #{misc.human_readable_size(MAX_BLOB_SIZE)} and you just tried to save one of size #{opts.blob.length/1000000}MB"
45
46
else if opts.check and opts.uuid != misc_node.uuidsha1(opts.blob)
47
err = "save_blob: uuid=#{opts.uuid} must be derived from the Sha1 hash of blob, but it is not (possible malicious attack)"
48
49
if err
50
dbg(err)
51
opts.cb(err)
52
return
53
54
# Store the blob in the database, if it isn't there already.
55
opts.database.save_blob
56
uuid : opts.uuid
57
blob : opts.blob
58
ttl : opts.ttl
59
project_id : opts.project_id
60
account_id : opts.account_id
61
cb : (err, ttl) =>
62
if err
63
dbg("failed to store blob -- #{err}")
64
else
65
dbg("successfully stored blob")
66
opts.cb(err, ttl)
67
68