public InfoModule(IPenguinUploadContext serverContext) { ServerContext = serverContext; Get("/tos", _ => ServerContext.Configuration.TermsOfService); }
public UserServiceTable(IPenguinUploadContext serverContext) { ServerContext = serverContext; }
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); }); }
public StoredFilesManager(IPenguinUploadContext serverContext) { ServerContext = serverContext; }
public AdminAccessModule(IPenguinUploadContext serverContext) : base("/api/admin") { ServerContext = serverContext; this.RequiresAuthentication(); // Requires API key access this.RequiresClaims(x => x.Value == ApiClientAuthenticationService.StatelessAuthClaim.Value); Before += (ctx) => { // Make sure user is an admin if (!ServerContext.IsAdministrator(Context.CurrentUser.Identity.Name)) { return(HttpStatusCode.Unauthorized); } return(null); }; // List all users Get("/enumerateusers", async _ => { var webUserManager = new WebUserManager(ServerContext); var allUsers = await webUserManager.GetAllUsersAsync(); return(Response.AsJsonNet(allUsers)); }); // Get user account info Get("/accountinfo/{name}", async args => { var userManager = new WebUserManager(ServerContext); var user = await userManager.FindUserByUsernameAsync((string)args.name); return(user == null ? HttpStatusCode.NotFound : Response.AsJsonNet(user)); }); // Disable a user's account Patch("/disableuser/{name}", async args => { var userManager = new WebUserManager(ServerContext); var user = await userManager.FindUserByUsernameAsync((string)args.name); if (user == null) { return(HttpStatusCode.BadRequest); } // Disable user await userManager.SetEnabledAsync(user, false); return(HttpStatusCode.OK); }); // Enable a user's account Patch("/enableuser/{name}", async args => { var userManager = new WebUserManager(ServerContext); var user = await userManager.FindUserByUsernameAsync((string)args.name); if (user == null) { return(HttpStatusCode.BadRequest); } // Disable user await userManager.SetEnabledAsync(user, true); return(HttpStatusCode.OK); }); // Get file info (admin override) Get("/fileinfo/{id}", async args => { var fileId = (string)args.id; // Get metadata var storedFilesManager = new StoredFilesManager(ServerContext); var storedFile = await storedFilesManager.GetStoredFileByIdentifierAsync(fileId); return(Response.AsJsonNet(storedFile)); }); // Download a file (admin override) Get("/downloadfile/{id}", async args => { var fileId = (string)args.id; // Get metadata var storedFilesManager = new StoredFilesManager(ServerContext); var storedFile = await storedFilesManager.GetStoredFileByIdentifierAsync(fileId); if (storedFile == null) { return(HttpStatusCode.NotFound); } var fileUploadHandler = new LocalStorageHandler(ServerContext, null, true); var fileStream = fileUploadHandler.RetrieveFileStream(storedFile.Identifier); var response = new StreamResponse(() => fileStream, MimeTypes.GetMimeType(storedFile.Name)); return(response.AsAttachment(storedFile.Name)); }); // Delete a file (admin override) Delete("/deletefile/{id}", async args => { var fileId = (string)args.id; // Remove physical file var fileUploadHandler = new LocalStorageHandler(ServerContext, null, true); await fileUploadHandler.DeleteFileAsync(fileId); // Unregister file var storedFilesManager = new StoredFilesManager(ServerContext); await storedFilesManager.UnregisterStoredFileAsync(fileId); return(HttpStatusCode.OK); }); // Quota management Patch("/updatequota/{name}/{quota}", async args => { var userManager = new WebUserManager(ServerContext); var user = await userManager.FindUserByUsernameAsync((string)args.name); if (user == null) { return(HttpStatusCode.BadRequest); } // Disable user await userManager.SetQuotaAsync(user, (int)args.quota); return(HttpStatusCode.OK); }); }
public AdHocApiAccessModule(IPenguinUploadContext serverContext) : base("/api") { ServerContext = serverContext; Get("/fileinfo/{idPass}", async args => { var idParts = ((string)args.idPass).Split('!'); var id = idParts[0]; string pass = null; if (idParts.Length > 1) { pass = idParts[1]; } var storedFilesManager = new StoredFilesManager(ServerContext); var storedFile = await storedFilesManager.GetPublicStoredFileByIdentifierAsync(id); if (storedFile == null) { return(HttpStatusCode.NotFound); } if (storedFile.IsPasswordProtected) { if (pass == null) { return(HttpStatusCode.Unauthorized); } // Make sure password matches if (!storedFile.CheckPassword(pass)) { return(HttpStatusCode.Unauthorized); } } return(Response.AsJsonNet(storedFile)); }); Get("/download/{idPass}", async args => { var idParts = ((string)args.idPass).Split('!'); var id = idParts[0]; var serveEmbed = ((string)Request.Query.embed) == "1"; string pass = null; if (idParts.Length > 1) { pass = idParts[1]; } var storedFilesManager = new StoredFilesManager(ServerContext); var storedFile = await storedFilesManager.GetPublicStoredFileByIdentifierAsync(id); if (storedFile == null) { return(HttpStatusCode.NotFound); } if (storedFile.IsPasswordProtected) { // Make sure password matches if (!storedFile.CheckPassword(pass)) { return(HttpStatusCode.Unauthorized); } } // Create unauthenticated storage handler without admin permissions // This is OK because download operation does not affect quota. var fileUploadHandler = new LocalStorageHandler(ServerContext, null, false); var fileStream = fileUploadHandler.RetrieveFileStream(storedFile.Identifier); var contentType = MimeTypes.GetMimeType(storedFile.Name); // serve depending on embed option if (serveEmbed) { // allow streamable download return(Response.FromPartialStream(Request, fileStream, contentType)); } else { var response = new StreamResponse(() => fileStream, contentType); return(response.AsAttachment(storedFile.Name)); } }); }
public RemoteAuthModule(IPenguinUploadContext serverContext) { ServerContext = serverContext; Post("/register", async args => { var req = this.Bind <RegistrationRequest>(); try { if (!ServerContext.Configuration.RegisterEnabled) { return(Response.AsText("Account registration has been disabled by the administrator.") .WithStatusCode(HttpStatusCode.Unauthorized)); } // Validate parameters! // Valdiate username length, charset if (req.Username.Length < 4) { throw new SecurityException("Username must be at least 4 characters."); } // Validate phone number // Validate password if (req.Password.Length < 8) { throw new SecurityException("Password must be at least 8 characters."); } if (req.Username.Length > 24) { throw new SecurityException("Username may not exceed 24 characters."); } if (req.Password.Length > 128) { throw new SecurityException("Password may not exceed 128 characters."); } // Check invite key if enabled if (!string.IsNullOrWhiteSpace(ServerContext.Configuration.InviteKey)) { if (req.InviteKey != ServerContext.Configuration.InviteKey) { throw new SecurityException("The invite key is not recognized."); } } // Validate registration var webUserManager = new WebUserManager(ServerContext); var newUser = await webUserManager.RegisterUserAsync(req); // Return user details return(Response.AsJsonNet(new RemoteAuthResponse { User = newUser, ApiKey = newUser.ApiKey })); } catch (NullReferenceException) { // A parameter was not provided return(HttpStatusCode.BadRequest); } catch (SecurityException secEx) { // Registration blocked for security reasons return(Response.AsText(secEx.Message) .WithStatusCode(HttpStatusCode.Unauthorized)); } }); Post("/login", async args => { var req = this.Bind <LoginRequest>(); var webUserManager = new WebUserManager(ServerContext); var selectedUser = await webUserManager.FindUserByUsernameAsync(req.Username); if (selectedUser == null) { return(HttpStatusCode.Unauthorized); } try { // Validate password if (selectedUser.Enabled && await webUserManager.CheckPasswordAsync(req.Password, selectedUser)) { // Return user details return(Response.AsJsonNet(new RemoteAuthResponse { User = selectedUser, ApiKey = selectedUser.ApiKey })); } return(HttpStatusCode.Unauthorized); } catch (NullReferenceException) { // A parameter was not provided return(HttpStatusCode.BadRequest); } catch (SecurityException secEx) { // Blocked for security reasons return(Response.AsText(secEx.Message) .WithStatusCode(HttpStatusCode.Unauthorized)); } }); Post("/reauth", async args => { var req = this.Bind <ReauthRequest>(); var webUserManager = new WebUserManager(ServerContext); var selectedUser = await webUserManager.FindUserByUsernameAsync(req.Username); if (selectedUser == null) { return(HttpStatusCode.Unauthorized); } try { // Validate key if (selectedUser.Enabled && selectedUser.ApiKey == req.ApiKey) { // Return user details return(Response.AsJsonNet(new RemoteAuthResponse { User = selectedUser, ApiKey = selectedUser.ApiKey })); } return(HttpStatusCode.Unauthorized); } catch (NullReferenceException) { // A parameter was not provided return(HttpStatusCode.BadRequest); } catch (SecurityException secEx) { // Blocked for security reasons return(Response.AsText(secEx.Message) .WithStatusCode(HttpStatusCode.Unauthorized)); } }); Patch("/changepassword", async args => { var req = this.Bind <ChangePasswordRequest>(); var webUserManager = new WebUserManager(ServerContext); var selectedUser = await webUserManager.FindUserByUsernameAsync(req.Username); try { // Validate password if (req.NewPassword.Length < 8) { throw new SecurityException("Password must be at least 8 characters."); } if (req.NewPassword.Length > 128) { throw new SecurityException("Password may not exceed 128 characters."); } if (selectedUser.Enabled && await webUserManager.CheckPasswordAsync(req.OldPassword, selectedUser)) { // Update password await webUserManager.ChangeUserPasswordAsync(selectedUser, req.NewPassword); return(HttpStatusCode.OK); } return(HttpStatusCode.Unauthorized); } catch (NullReferenceException) { // A parameter was not provided return(new Response().WithStatusCode(HttpStatusCode.BadRequest)); } catch (SecurityException secEx) { // Registration blocked for security reasons return(Response.AsText(secEx.Message) .WithStatusCode(HttpStatusCode.Unauthorized)); } }); }
public ApiClientAuthenticationService(IPenguinUploadContext serverContext) { ServerContext = serverContext; }
public LocalStorageHandler(IPenguinUploadContext serverContext, string owner, bool adminOverride = false) { ServerContext = serverContext; _owner = owner; _adminOverride = adminOverride; }
public WebUserManager(IPenguinUploadContext serverContext) { ServerContext = serverContext; }
public PenguinUploadBootstrapper(IPenguinUploadContext serverContext) { ServerContext = serverContext; }