createUploadSession method

JsonMap createUploadSession(
  1. String principalId,
  2. String channelId,
  3. JsonMap body
)

createUpload (12 3.1): a session for an UploadCreate body of principalId in channelId, with the parts of FakeFileSettings.partBytes.

Throws 404 for a channel the principal does not see, 403 forbidden below write, 413 payload_too_large above file_max_upload_bytes.

Implementation

JsonMap createUploadSession(
  String principalId,
  String channelId,
  JsonMap body,
) {
  if (!seesChannel(principalId, channelId)) {
    throw const FakeProblem(404, 'not_found');
  }
  final level = levelOf(principalId, channelId);
  if (level == 'read') throw const FakeProblem(403, 'forbidden');
  final size = body['size_bytes']! as int;
  if (size > (limits['file_max_upload_bytes']! as int)) {
    throw const FakeProblem(413, 'payload_too_large');
  }
  final id = nextId();
  final name = (body['name']! as String).split(RegExp(r'[/\\]')).last;
  final file = FakeFile({
    'id': id,
    'sha256': body['sha256'],
    'size_bytes': size,
    'mime_type': 'application/octet-stream',
    'original_name': name.isEmpty ? 'file' : name,
    'uploaded_by': principalId,
    'purpose': 'attachment',
    'scope_channel_id': channelId,
    'upload_state': 'pending',
    'scan_status': 'pending',
    'transcript_status': 'none',
    'thumbnails': <Object?>[],
    'created_at': stamp(),
  });
  final settings = fileSettings;
  file
    ..partBytes = settings.partBytes
    ..partCount = (size + settings.partBytes - 1) ~/ settings.partBytes
    ..declaredSha256 = body['sha256']! as String
    ..declaredMime =
        body['declared_mime_type'] as String? ?? 'application/octet-stream'
    ..expiresAt = now().add(const Duration(hours: 24));
  files[id] = file;
  return {
    'file_id': id,
    'mode': settings.mode,
    'part_size_bytes': file.partBytes,
    'parts': [
      for (var n = 1; n <= file.partCount; n++)
        {
          'part_number': n,
          'url': settings.mode == 'presigned'
              ? '/objectstore/$id/$n'
              : '/api/v1/uploads/$id/parts/$n',
          'headers': [
            {'name': 'Content-Type', 'value': 'application/octet-stream'},
          ],
        },
    ],
    'expires_at': stamp(file.expiresAt),
  };
}