Beispiel #1
0
        public ApiAccessModule(IPenguinUploadContext serverContext) : base("/api")
        {
            ServerContext = serverContext;
            this.RequiresAuthentication();
            // Requires API key access
            this.RequiresClaims(x => x.Value == ApiClientAuthenticationService.StatelessAuthClaim.Value);

            var userManager = new WebUserManager(ServerContext);

            // Get user metadata
            Get("/userinfo", async _ =>
            {
                var idUsername = Context.CurrentUser.Identity.Name;
                var user       = await userManager.FindUserByUsernameAsync(idUsername);
                return(Response.AsJsonNet(user));
            });

            // Generate new API key
            Patch("/newkey", async _ =>
            {
                var idUsername = Context.CurrentUser.Identity.Name;
                var user       = await userManager.FindUserByUsernameAsync(idUsername);
                // Update key
                await userManager.GenerateNewApiKeyAsync(user);
                return(Response.AsJsonNet(user));
            });

            // Get list of files
            Get("/files", async _ =>
            {
                var idUsername         = Context.CurrentUser.Identity.Name;
                var user               = await userManager.FindUserByUsernameAsync(idUsername);
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var userFiles          = await storedFilesManager.GetStoredFilesByUserAsync(user);
                var directoryStructure = FileOrganization.BuildStructure(userFiles);
                return(Response.AsJsonNet(directoryStructure));
            });

            // Upload a file
            Post("/upload", async _ =>
            {
                var idUsername        = Context.CurrentUser.Identity.Name;
                var request           = this.Bind <FileUploadRequest>();
                var fileUploadHandler = new LocalStorageHandler(ServerContext, idUsername);
                FileUploadResult uploadResult;
                try
                {
                    uploadResult =
                        await fileUploadHandler.HandleUploadAsync(request.File.Name, request.File.Value);
                }
                catch (QuotaExceededException qEx)
                {
                    return(Response.AsText(qEx.Message).WithStatusCode(HttpStatusCode.Forbidden));
                }

                // Register uploaded file
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var storedFile         =
                    await storedFilesManager.RegisterStoredFileAsync(idUsername,
                                                                     request.File.Name, request.TargetDirectory, uploadResult.FileId,
                                                                     uploadResult.Size);

                return(Response.AsJsonNet(storedFile));
            });

            // Force download, bypass password
            Get("/fdownload/{id}", async args =>
            {
                var idUsername         = Context.CurrentUser.Identity.Name;
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var storedFile         = await storedFilesManager.GetStoredFileByIdentifierAsync((string)args.id);
                if (storedFile == null)
                {
                    return(HttpStatusCode.NotFound);
                }

                var fileUploadHandler = new LocalStorageHandler(ServerContext, idUsername);
                var fileStream        = fileUploadHandler.RetrieveFileStream(storedFile.Identifier);
                var response          = new StreamResponse(() => fileStream, MimeTypes.GetMimeType(storedFile.Name));
                return(response.AsAttachment(storedFile.Name));
            });

            // Set a password on a file
            Patch("/lock/{idPass}", async args =>
            {
                var idParts = ((string)args.idPass).Split('!');
                if (idParts.Length < 2)
                {
                    return(HttpStatusCode.BadRequest);
                }
                var id   = idParts[0];
                var pass = idParts[1];
                if (pass.Length > 128)
                {
                    return(Response.AsText("Password cannot exceed 128 characters.")
                           .WithStatusCode(HttpStatusCode.BadRequest));
                }
                // Update file metadata
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var storedFile         = await storedFilesManager.GetStoredFileByIdentifierAsync(id);
                if (storedFile == null)
                {
                    return(HttpStatusCode.BadRequest);
                }
                await storedFilesManager.SetFilePasswordAsync(storedFile, pass);
                return(HttpStatusCode.OK);
            });

            // Unset a password on a file
            Patch("/unlock/{id}", async args =>
            {
                var id = (string)args.id;
                // Update file metadata
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var storedFile         = await storedFilesManager.GetStoredFileByIdentifierAsync(id);
                if (storedFile == null)
                {
                    return(HttpStatusCode.BadRequest);
                }
                await storedFilesManager.SetFilePasswordAsync(storedFile, null);
                return(HttpStatusCode.OK);
            });

            Patch("/rename/{id}/{name}", async args =>
            {
                var id      = (string)args.id;
                var newname = (string)args.name;
                // Update file metadata
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var storedFile         = await storedFilesManager.GetStoredFileByIdentifierAsync(id);
                if (storedFile == null)
                {
                    return(HttpStatusCode.BadRequest);
                }
                storedFile.Name = newname;
                await storedFilesManager.UpdateStoredFileInDatabaseAsync(storedFile);
                return(HttpStatusCode.OK);
            });

            // Delete a file
            Delete("/delete/{id}", async args =>
            {
                var idUsername = Context.CurrentUser.Identity.Name;
                var fileId     = (string)args.id;
                // Remove physical file
                var fileUploadHandler = new LocalStorageHandler(ServerContext, idUsername);
                await fileUploadHandler.DeleteFileAsync(fileId);
                // Unregister file
                var storedFilesManager = new StoredFilesManager(ServerContext);
                await storedFilesManager.UnregisterStoredFileAsync(fileId);
                return(HttpStatusCode.OK);
            });

            // Nuke (batch destroy)

            // Delete all a user's files
            Delete("/nuke/files", async _ =>
            {
                var idUsername         = Context.CurrentUser.Identity.Name;
                var user               = await userManager.FindUserByUsernameAsync(idUsername);
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var fileUploadHandler  = new LocalStorageHandler(ServerContext, idUsername);
                // Start tasks to nuke user's files
                var userFiles             = await storedFilesManager.GetStoredFilesByUserAsync(user);
                var nukePhysicalFilesTask = fileUploadHandler.NukeAllFilesAsync(userFiles.Select(x => x.Identifier));
                var nukeFilesTask         = storedFilesManager.NukeAllFilesAsync(user);
                return(HttpStatusCode.OK);
            });

            // Delete a user and all content
            Delete("/nuke/user", async _ =>
            {
                var idUsername = Context.CurrentUser.Identity.Name;
                var user       = await userManager.FindUserByUsernameAsync(idUsername);
                // Disable user
                await userManager.SetEnabledAsync(user, false);
                var storedFilesManager = new StoredFilesManager(ServerContext);
                var fileUploadHandler  = new LocalStorageHandler(ServerContext, idUsername);
                // Start tasks to nuke user's files
                var userFiles             = await storedFilesManager.GetStoredFilesByUserAsync(user);
                var nukePhysicalFilesTask = fileUploadHandler.NukeAllFilesAsync(userFiles.Select(x => x.Identifier));
                var nukeFilesTask         = storedFilesManager.NukeAllFilesAsync(user);
                await nukeFilesTask;
                await nukePhysicalFilesTask;
                // Now nuke the user
                await userManager.RemoveUserAsync(user.Username);
                return(HttpStatusCode.OK);
            });
        }