🐛 Fix missing file permission creation

This commit is contained in:
2026-01-12 19:32:50 +08:00
parent 7085f43e54
commit c11bf579c4
12 changed files with 158 additions and 3 deletions

View File

@@ -45,6 +45,9 @@ public class CustomAppService(
if (picture is null) if (picture is null)
throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud."); throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud.");
app.Picture = SnCloudFileReferenceObject.FromProtoValue(picture); app.Picture = SnCloudFileReferenceObject.FromProtoValue(picture);
if (request.Status == Shared.Models.CustomAppStatus.Production)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
{ {
@@ -54,6 +57,9 @@ public class CustomAppService(
if (background is null) if (background is null)
throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud."); throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud.");
app.Background = SnCloudFileReferenceObject.FromProtoValue(background); app.Background = SnCloudFileReferenceObject.FromProtoValue(background);
if (request.Status == Shared.Models.CustomAppStatus.Production)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.CustomApps.Add(app); db.CustomApps.Add(app);
@@ -164,6 +170,7 @@ public class CustomAppService(
public async Task<SnCustomApp?> UpdateAppAsync(SnCustomApp app, CustomAppController.CustomAppRequest request) public async Task<SnCustomApp?> UpdateAppAsync(SnCustomApp app, CustomAppController.CustomAppRequest request)
{ {
var oldStatus = app.Status;
if (request.Slug is not null) if (request.Slug is not null)
app.Slug = request.Slug; app.Slug = request.Slug;
if (request.Name is not null) if (request.Name is not null)
@@ -188,6 +195,9 @@ public class CustomAppService(
if (picture is null) if (picture is null)
throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud."); throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud.");
app.Picture = SnCloudFileReferenceObject.FromProtoValue(picture); app.Picture = SnCloudFileReferenceObject.FromProtoValue(picture);
if (app.Status == Shared.Models.CustomAppStatus.Production)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
{ {
@@ -197,11 +207,29 @@ public class CustomAppService(
if (background is null) if (background is null)
throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud."); throw new InvalidOperationException("Invalid picture id, unable to find the file on cloud.");
app.Background = SnCloudFileReferenceObject.FromProtoValue(background); app.Background = SnCloudFileReferenceObject.FromProtoValue(background);
if (app.Status == Shared.Models.CustomAppStatus.Production)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Update(app); db.Update(app);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
if (oldStatus != Shared.Models.CustomAppStatus.Production && app.Status == Shared.Models.CustomAppStatus.Production)
{
if (app.Picture is not null)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = app.Picture.Id });
if (app.Background is not null)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = app.Background.Id });
}
else if (oldStatus == Shared.Models.CustomAppStatus.Production && app.Status != Shared.Models.CustomAppStatus.Production)
{
if (app.Picture is not null)
await files.UnsetFilePublicAsync(new UnsetFilePublicRequest { FileId = app.Picture.Id });
if (app.Background is not null)
await files.UnsetFilePublicAsync(new UnsetFilePublicRequest { FileId = app.Background.Id });
}
return app; return app;
} }

View File

@@ -80,9 +80,6 @@ public class FileController(
if (currentUser?.IsSuperuser == true) if (currentUser?.IsSuperuser == true)
return true; return true;
// TODO Remove this when the other serivce will mark permission correctly.
return true;
var permission = await db.FilePermissions var permission = await db.FilePermissions
.FirstOrDefaultAsync(p => p.FileId == file.Id); .FirstOrDefaultAsync(p => p.FileId == file.Id);

View File

@@ -854,6 +854,45 @@ public class FileService(
await db.SaveChangesAsync(); await db.SaveChangesAsync();
return count; return count;
} }
public async Task SetPublicAsync(string fileId)
{
var existingPermission = await db.FilePermissions
.FirstOrDefaultAsync(p =>
p.FileId == fileId &&
p.SubjectType == SnFilePermissionType.Anyone &&
p.Permission == SnFilePermissionLevel.Read);
if (existingPermission != null)
return;
var permission = new SnFilePermission
{
Id = Guid.NewGuid(),
FileId = fileId,
SubjectType = SnFilePermissionType.Anyone,
SubjectId = string.Empty,
Permission = SnFilePermissionLevel.Read
};
db.FilePermissions.Add(permission);
await db.SaveChangesAsync();
}
public async Task UnsetPublicAsync(string fileId)
{
var permission = await db.FilePermissions
.FirstOrDefaultAsync(p =>
p.FileId == fileId &&
p.SubjectType == SnFilePermissionType.Anyone &&
p.Permission == SnFilePermissionLevel.Read);
if (permission == null)
return;
db.FilePermissions.Remove(permission);
await db.SaveChangesAsync();
}
} }
file class UpdatableCloudFile(SnCloudFile file) file class UpdatableCloudFile(SnCloudFile file)

View File

@@ -46,5 +46,17 @@ namespace DysonNetwork.Drive.Storage
await fileService._PurgeCacheAsync(request.FileId); await fileService._PurgeCacheAsync(request.FileId);
return new Empty(); return new Empty();
} }
public override async Task<Empty> SetFilePublic(SetFilePublicRequest request, ServerCallContext context)
{
await fileService.SetPublicAsync(request.FileId);
return new Empty();
}
public override async Task<Empty> UnsetFilePublic(UnsetFilePublicRequest request, ServerCallContext context)
{
await fileService.UnsetPublicAsync(request.FileId);
return new Empty();
}
} }
} }

View File

@@ -122,12 +122,16 @@ public class AccountCurrentController(
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId }); var file = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId });
profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file); profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId }); var file = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId });
profile.Background = SnCloudFileReferenceObject.FromProtoValue(file); profile.Background = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Update(profile); db.Update(profile);

View File

@@ -229,12 +229,16 @@ public class AccountService(
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = pictureId }); var file = await files.GetFileAsync(new GetFileRequest { Id = pictureId });
account.Profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file); account.Profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = pictureId });
} }
if (!string.IsNullOrEmpty(backgroundId)) if (!string.IsNullOrEmpty(backgroundId))
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = backgroundId }); var file = await files.GetFileAsync(new GetFileRequest { Id = backgroundId });
account.Profile.Background = SnCloudFileReferenceObject.FromProtoValue(file); account.Profile.Background = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = backgroundId });
} }
db.Accounts.Add(account); db.Accounts.Add(account);

View File

@@ -53,12 +53,16 @@ public class BotAccountReceiverGrpc(
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId }); var file = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId });
account.Profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file); account.Profile.Picture = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
{ {
var file = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId }); var file = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId });
account.Profile.Background = SnCloudFileReferenceObject.FromProtoValue(file); account.Profile.Background = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Accounts.Update(account); db.Accounts.Update(account);

View File

@@ -388,6 +388,9 @@ public class RealmController(
var pictureResult = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId }); var pictureResult = await files.GetFileAsync(new GetFileRequest { Id = request.PictureId });
if (pictureResult is null) return BadRequest("Invalid picture id, unable to find the file on cloud."); if (pictureResult is null) return BadRequest("Invalid picture id, unable to find the file on cloud.");
realm.Picture = SnCloudFileReferenceObject.FromProtoValue(pictureResult); realm.Picture = SnCloudFileReferenceObject.FromProtoValue(pictureResult);
if (realm.IsPublic)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
@@ -395,6 +398,9 @@ public class RealmController(
var backgroundResult = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId }); var backgroundResult = await files.GetFileAsync(new GetFileRequest { Id = request.BackgroundId });
if (backgroundResult is null) return BadRequest("Invalid background id, unable to find the file on cloud."); if (backgroundResult is null) return BadRequest("Invalid background id, unable to find the file on cloud.");
realm.Background = SnCloudFileReferenceObject.FromProtoValue(backgroundResult); realm.Background = SnCloudFileReferenceObject.FromProtoValue(backgroundResult);
if (realm.IsPublic)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Realms.Add(realm); db.Realms.Add(realm);
@@ -456,6 +462,9 @@ public class RealmController(
if (pictureResult is null) return BadRequest("Invalid picture id, unable to find the file on cloud."); if (pictureResult is null) return BadRequest("Invalid picture id, unable to find the file on cloud.");
realm.Picture = SnCloudFileReferenceObject.FromProtoValue(pictureResult); realm.Picture = SnCloudFileReferenceObject.FromProtoValue(pictureResult);
if (realm.IsPublic)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
@@ -464,10 +473,14 @@ public class RealmController(
if (backgroundResult is null) return BadRequest("Invalid background id, unable to find the file on cloud."); if (backgroundResult is null) return BadRequest("Invalid background id, unable to find the file on cloud.");
realm.Background = SnCloudFileReferenceObject.FromProtoValue(backgroundResult); realm.Background = SnCloudFileReferenceObject.FromProtoValue(backgroundResult);
if (realm.IsPublic)
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Realms.Update(realm); db.Realms.Update(realm);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
await db.SaveChangesAsync();
als.CreateActionLogFromRequest( als.CreateActionLogFromRequest(
"realms.update", "realms.update",

View File

@@ -70,6 +70,12 @@ service FileService {
// Purge cache for a file // Purge cache for a file
rpc PurgeCache(PurgeCacheRequest) returns (google.protobuf.Empty); rpc PurgeCache(PurgeCacheRequest) returns (google.protobuf.Empty);
// Set file as publicly readable (anyone read permission)
rpc SetFilePublic(SetFilePublicRequest) returns (google.protobuf.Empty);
// Remove public read permission
rpc UnsetFilePublic(UnsetFilePublicRequest) returns (google.protobuf.Empty);
} }
// Request message for GetFile // Request message for GetFile
@@ -113,3 +119,11 @@ message DeleteFileRequest {
message PurgeCacheRequest { message PurgeCacheRequest {
string file_id = 1; string file_id = 1;
} }
message SetFilePublicRequest {
string file_id = 1;
}
message UnsetFilePublicRequest {
string file_id = 1;
}

View File

@@ -163,6 +163,14 @@ public partial class PostService(
post.Attachments = attachments post.Attachments = attachments
.Select(id => post.Attachments.First(a => a.Id == id)) .Select(id => post.Attachments.First(a => a.Id == id))
.ToList(); .ToList();
if (post.Visibility == Shared.Models.PostVisibility.Public)
{
foreach (var attachment in post.Attachments)
{
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = attachment.Id });
}
}
} }
if (tags is not null) if (tags is not null)
@@ -326,9 +334,25 @@ public partial class PostService(
throw new InvalidOperationException("Categories contains one or more categories that wasn't exists."); throw new InvalidOperationException("Categories contains one or more categories that wasn't exists.");
} }
var oldVisibility = post.Visibility;
db.Update(post); db.Update(post);
await db.SaveChangesAsync(); await db.SaveChangesAsync();
if (post.Visibility == Shared.Models.PostVisibility.Public && oldVisibility != Shared.Models.PostVisibility.Public)
{
foreach (var attachment in post.Attachments)
{
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = attachment.Id });
}
}
else if (oldVisibility == Shared.Models.PostVisibility.Public && post.Visibility != Shared.Models.PostVisibility.Public)
{
foreach (var attachment in post.Attachments)
{
await files.UnsetFilePublicAsync(new UnsetFilePublicRequest { FileId = attachment.Id });
}
}
// Process link preview in the background to avoid delaying post update // Process link preview in the background to avoid delaying post update
_ = Task.Run(async () => await CreateLinkPreviewAsync(post)); _ = Task.Run(async () => await CreateLinkPreviewAsync(post));

View File

@@ -374,6 +374,8 @@ public class PublisherController(
"Invalid picture id, unable to find the file on cloud." "Invalid picture id, unable to find the file on cloud."
); );
picture = SnCloudFileReferenceObject.FromProtoValue(queryResult); picture = SnCloudFileReferenceObject.FromProtoValue(queryResult);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
@@ -386,6 +388,8 @@ public class PublisherController(
"Invalid background id, unable to find the file on cloud." "Invalid background id, unable to find the file on cloud."
); );
background = SnCloudFileReferenceObject.FromProtoValue(queryResult); background = SnCloudFileReferenceObject.FromProtoValue(queryResult);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
var publisher = await ps.CreateIndividualPublisher( var publisher = await ps.CreateIndividualPublisher(
@@ -471,6 +475,8 @@ public class PublisherController(
"Invalid picture id, unable to find the file on cloud." "Invalid picture id, unable to find the file on cloud."
); );
picture = SnCloudFileReferenceObject.FromProtoValue(queryResult); picture = SnCloudFileReferenceObject.FromProtoValue(queryResult);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
@@ -483,6 +489,8 @@ public class PublisherController(
"Invalid background id, unable to find the file on cloud." "Invalid background id, unable to find the file on cloud."
); );
background = SnCloudFileReferenceObject.FromProtoValue(queryResult); background = SnCloudFileReferenceObject.FromProtoValue(queryResult);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
var publisher = await ps.CreateOrganizationPublisher( var publisher = await ps.CreateOrganizationPublisher(
@@ -569,6 +577,8 @@ public class PublisherController(
var picture = SnCloudFileReferenceObject.FromProtoValue(queryResult); var picture = SnCloudFileReferenceObject.FromProtoValue(queryResult);
publisher.Picture = picture; publisher.Picture = picture;
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.PictureId });
} }
if (request.BackgroundId is not null) if (request.BackgroundId is not null)
@@ -583,6 +593,8 @@ public class PublisherController(
var background = SnCloudFileReferenceObject.FromProtoValue(queryResult); var background = SnCloudFileReferenceObject.FromProtoValue(queryResult);
publisher.Background = background; publisher.Background = background;
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.BackgroundId });
} }
db.Update(publisher); db.Update(publisher);

View File

@@ -155,6 +155,8 @@ public class StickerController(
return BadRequest("Icon not found."); return BadRequest("Icon not found.");
pack.Icon = SnCloudFileReferenceObject.FromProtoValue(file); pack.Icon = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.IconId });
} }
db.StickerPacks.Add(pack); db.StickerPacks.Add(pack);
@@ -197,6 +199,8 @@ public class StickerController(
return BadRequest("Icon not found."); return BadRequest("Icon not found.");
pack.Icon = SnCloudFileReferenceObject.FromProtoValue(file); pack.Icon = SnCloudFileReferenceObject.FromProtoValue(file);
await files.SetFilePublicAsync(new SetFilePublicRequest { FileId = request.IconId });
} }
db.StickerPacks.Update(pack); db.StickerPacks.Update(pack);