// New object public DbxObject(Instance instance, string type, Dictionary<string, object> properties, string srcuid, BlobDetails blob = null) { // Start createMode createMode = true; // Set magic property default this.instance = instance; this.magicOid = 0; this.magicUid = Uids.Generate(type); this.magicType = type; this.magicSerial = Util.SerialNow(); this.magicPredecessor = 0; this.magicCreator = srcuid; // Check access var userLevel = UserLevel(srcuid); if (!DbxObject.Creatable(instance, srcuid, type)) throw new UserErrorException("access.create", "Access violation attempt while creating object '" + type + "' (object level " + userLevel + ")"); // Enable writing writable = true; // Prepare properties this.properties = new Dictionary<string, object>(); // Make sure properties isn't null if (null == properties) properties = new Dictionary<string, object>(); // If property is not defined - set it to be the detault. This is to make sure all triggers and particularly null constraints are fired foreach (var item in Subschema.Properties) { if (!properties.ContainsKey(item.Key) && AccessFields(srcuid, false, true).Contains(item.Key)) { properties[item.Key] = item.Value.DefaultValue; } } // Set properties Set(properties, srcuid, true); // Set blob data if (null != Subschema.Blob) { try { SetBlob(srcuid, blob); } catch (UserErrorException) { // Error occured creating blob - rollback database entry Delete("system"); // Throw error anyway throw; } } // Create trigger (PROBABLY SHOULD HAPPEN BEFORE SET, but validation wouldn't have happened yet) instance.Mode.TriggerCreating(this, magicType, properties, blob, srcuid); // Stop createMode createMode = false; }
public override void TriggerCreating(DbxObject newobj, string type, Dictionary<string, object> properties, BlobDetails blob, string srcuid) { if (type == "child") { // Set last report date newobj.Set(new Dictionary<string, object>() { { "lastProgressReport", DateTime.UtcNow.ToString("o") }, { "subscriptionStartDate", DateTime.UtcNow.ToString("o") }, { "subscriptionEndDate", DateTime.UtcNow.AddMonths(+1).ToString("o") } }, "system"); } if (type == "report") { // Load user DbxObject user; string userAname = ""; string userUid = ""; if (properties.ContainsKey("user") && !string.IsNullOrEmpty((string)properties["user"])) { user = instance.Uid((string)properties["user"]); userAname = (string)user.GetProp("aname", "system"); userUid = user.Uid; } // Create state file var path = Path.GetTempPath() + Path.GetRandomFileName(); Directory.CreateDirectory(path); var pageStateFile = path + "\\pageState.html_"; Util.PutContents(pageStateFile, (string)properties["pageState"]); // Compose email var message = SendGrid.GetInstance(); message.AddTo("*****@*****.**"); message.From = new MailAddress("*****@*****.**", "KidsPB Contact"); message.Html = "" + "<p><strong>Type: </strong> " + Util.EncodeHTML((string)properties["type"]) + "</p>" + "<p><strong>User: </strong> " + Util.EncodeHTML(userAname) + " [" + userUid + "] (" + Util.EncodeHTML((string)properties["email"]) + ")</p>" + "<p><strong>Message: </strong> " + Util.EncodeHTML((string)properties["message"]) + "</p>" + "<p><strong>Log: </strong><br /><pre>" + Util.EncodeHTML((string)properties["log"]) + "</pre></p>" + ""; message.Subject = "Contact from '" + userAname + "'"; message.AddAttachment(pageStateFile); message.DisableFooter(); message.DisableTemplate(); var emailtransport = SendGridMail.Transport.Web.GetInstance(new NetworkCredential(GridMailUsername, GridMailPassword)); emailtransport.Deliver(message); } if (type == "post") { // Focus string PostFocus; if (null == properties["focus"]) { PostFocus = "Personal Best"; } else { var Focus = instance.Uid((string)properties["focus"]); PostFocus = Util.EncodeHTML((string)Focus.GetProp("title", "system")); } // Aname var PostAname = Util.EncodeHTML((string)instance.Uid((string)properties["member"]).GetProp("aname", "system")); // Message var PostMessage = Util.EncodeHTML((string)properties["message"]); // Date var PostDate = DateTime.Parse((string)properties["date"], null, System.Globalization.DateTimeStyles.RoundtripKind); var Message = "<p>Post by " + "<strong>" + PostAname + "</strong> on <em>" + PostFocus + "<br />" + "\"" + PostMessage + "\"" + "<br /><em>" + PostDate.ToString("m") + "</em>" + "</p>" + "<p>Reply to this email and it will be added as a comment.</p>"; // Find allowed members (leave empty if unrestricted) var allowedmembers = null == properties["focus"] ? new HashSet<object>() : instance.Index.GetProperty((string)properties["focus"], "members"); // Load child var child = instance.Uid((string)properties["child"]); // Iterate all members of the community foreach (var muid in instance.Index.UidsMatching("member", Locate.GenerateSimple("child", properties["child"]))) { // If restricting is active for the focus, skip non-included members if (allowedmembers.Count > 0 && !allowedmembers.Contains(muid)) continue; // Get user UID, skip if no UID available (non-invited member) var userprop = instance.Index.GetProperty(muid, "user"); if (userprop.Count == 0) continue; var uuid = (string)userprop.Pop(); // Skip user if no longer exists if (!instance.Index.ContainsUid(uuid)) continue; // Skip user if they don't want messages if ((int)instance.Index.GetProperty(uuid, "emailFrequency").Pop() < 0) continue; // Skip if this is the posting user if (uuid == srcuid) continue; // Add message to queue instance.Create("mailqueue", "system", new Dictionary<string, object>(){ {"user", uuid}, {"email", UidToEmail(newobj.Uid)}, {"subject", "Re: " + PostFocus + " ("+child.GetProp("aname", "system")+"\'s Community)"}, {"type", "newpost"}, {"message", Message} }); } } if (type == "comment") { var Post = instance.Uid((string)properties["post"]); // Focus string PostFocus; DbxObject Focus = null; if (null == Post.GetProp("focus", "system")) { PostFocus = "Personal Best"; } else { Focus = instance.Uid((string)Post.GetProp("focus", "system")); PostFocus = Util.EncodeHTML((string)Focus.GetProp("title", "system")); } // Aname var PostAname = Util.EncodeHTML((string)instance.Uid((string)properties["member"]).GetProp("aname", "system")); // Message var PostMessage = Util.EncodeHTML((string)properties["message"]); // Date var PostDate = DateTime.Parse((string)properties["date"], null, System.Globalization.DateTimeStyles.RoundtripKind); var Message = "<p>Comment by " + "<strong>" + PostAname + "</strong> on <em>" + PostFocus + "<br />" + "\"" + PostMessage + "\"" + "<br /><em>" + PostDate.ToString("m") + "</em>" + "</p>"; // Find allowed members var allowedmembers = null == Focus ? new ArrayList() : (ArrayList)Focus.GetProp("members", "system"); // Load child var child = instance.Uid((string)Post.GetProp("child", "system")); // Iterate all members of the community foreach (var muid in instance.Index.UidsMatching("member", Locate.GenerateSimple("child", Post.GetProp("child", "system")))) { // If restricting is active for the focus, skip non-included members if (allowedmembers.Count > 0 && !allowedmembers.Contains(muid)) continue; // Get user UID, skip if no UID available (non-invited member) var userprop = instance.Index.GetProperty(muid, "user"); if (userprop.Count == 0) continue; var uuid = (string)userprop.Pop(); // Skip user if no longer exists if (!instance.Index.ContainsUid(uuid)) continue; // Skip user if they don't want messages if ((int)instance.Index.GetProperty(uuid, "emailFrequency").Pop() < 0) continue; // Skip if this is the posting user if (uuid == srcuid) continue; // Add message to queue instance.Create("mailqueue", "system", new Dictionary<string, object>(){ {"user", uuid}, {"email", UidToEmail(Post.Uid)}, {"subject", "Re: Comment ("+child.GetProp("aname", "system")+"\'s Community)"}, {"type", "newcomment"}, {"message", Message} }); } } if (type == "library") { MemoryStream outstream; BlobDetails newblob; DbxObject page; string icon = null; // Prepare properties var pageprops = new Dictionary<string, object>(); pageprops["library"] = newobj.Uid; // Determine input type switch (blob.ContentType) { case "application/pdf": // Render to multiple images // Load the PDF file. using (var file = PDFFile.Open(blob.Stream)) { file.SerialNumber = "PDFVW4WIN-RQF7C-87MFM-4BR91-5A1AO-B683E"; for (int i = 0; i < file.PageCount; i++) { // Get image as stream outstream = new MemoryStream(); file.GetPageImage(i, 150).Save(outstream, System.Drawing.Imaging.ImageFormat.Jpeg); // Prepare blob details newblob = new BlobDetails(outstream, "page" + (i + 1) + ".jpg", "image/jpeg", outstream.Length); // Prepare properties pageprops["page"] = ((int)i + 1); // Create instance outstream.Position = 0; page = instance.Create("libraryPage", srcuid, pageprops, newblob); // Note icon (first page) if (null == icon) icon = page.Uid; } } break; case "image/jpeg": // Create instance pageprops["page"] = 1; page = instance.Create("libraryPage", srcuid, pageprops, blob); // Note icon icon = page.Uid; break; case "image/png": // Convert to bitmap var bitmap = new Bitmap(blob.Stream); // Convert to PNG in stream outstream = new MemoryStream(); bitmap.Save(outstream, System.Drawing.Imaging.ImageFormat.Jpeg); outstream.Position = 0; // Prepare blob details newblob = new BlobDetails(outstream, "page1.jpg", "image/jpeg", outstream.Length); // Create instance pageprops["page"] = 1; page = instance.Create("libraryPage", srcuid, pageprops, newblob); // Note icon icon = page.Uid; break; default: throw new Exception("Should never happen - schema error allowed bad condition?"); } // Seed skipped properties with defaults var baseprops = new Dictionary<string, object>(); if (!properties.ContainsKey("title") || String.IsNullOrEmpty((string)properties["title"])) baseprops["title"] = blob.Filename.substr(0, 100); if (!properties.ContainsKey("details") || String.IsNullOrEmpty((string)properties["details"])) baseprops["details"] = ""; if (!properties.ContainsKey("dateUploaded") || String.IsNullOrEmpty((string)properties["dateUploaded"])) baseprops["dateUploaded"] = DateTime.UtcNow.ToString("o"); if (!properties.ContainsKey("dateRelevance") || String.IsNullOrEmpty((string)properties["dateRelevance"])) baseprops["dateRelevance"] = DateTime.UtcNow.ToString("o"); if (!properties.ContainsKey("icon") || String.IsNullOrEmpty((string)properties["icon"])) baseprops["icon"] = icon; newobj.Set(baseprops, srcuid); } if (type == "progressReport") { // Find associated child var childobj = instance.Uid((string)properties["child"]).GetWritableInstance(); // Update last report date childobj.Set(new Dictionary<string, object>() { { "lastProgressReport", DateTime.UtcNow.ToString("o") } }, "system"); } }
public override void TriggerCreating(DbxObject newobj, string type, Dictionary<string, object> properties, BlobDetails blob, string srcuid) { if (type == "report") { var user = instance.Uid((string)properties["src"]); var message = SendGrid.GetInstance(); message.AddTo("*****@*****.**"); message.From = new MailAddress("*****@*****.**", "Mission Platform Contact"); message.Html = "<html>" + "<p><strong>Type: </strong> " + Util.EncodeHTML((string)properties["type"]) + "</p>" + "<p><strong>User: </strong> <a href=\"" + user.GetProp("fbLink", "system") + "\">" + Util.EncodeHTML((string)user.GetProp("aname", "system")) + "</a> (" + user.GetProp("email", "system") + ")</p>" + "<p><strong>Message: </strong> " + Util.EncodeHTML((string)properties["message"]) + "</html>"; message.Subject = "Contact from '" + user.GetProp("aname", "system") + "'"; var emailtransport = SendGridMail.Transport.Web.GetInstance(new NetworkCredential(GridMailUsername, GridMailPassword)); emailtransport.Deliver(message); } if (type == "initiativeContact") { var initiative = instance.Uid((string)properties["initiative"]); var user = String.IsNullOrEmpty((string)properties["src"]) ? null : instance.Uid((string)properties["src"]); // Compose message text var messageText = new StringBuilder(); if (null != user) messageText.AppendLine("<p><strong>User: </strong> <a href=\"" + user.GetProp("fbLink", "system") + "\">" + Util.EncodeHTML((string)user.GetProp("aname", "system")) + "</a> (Registered using " + user.GetProp("email", "system") + ")</p>"); if (properties.ContainsKey("email")) messageText.AppendLine("<p><strong>Email: </strong> " + Util.EncodeHTML((string)properties["email"]) + "</p>"); if (properties.ContainsKey("phone")) messageText.AppendLine("<p><strong>Phone: </strong> " + Util.EncodeHTML((string)properties["phone"]) + "</p>"); messageText.AppendLine("<p><strong>Message: </strong> " + Util.EncodeHTML((string)properties["message"]) + "</p>"); // Send email var message = SendGrid.GetInstance(); message.AddTo((string)initiative.GetProp("email", "system")); message.AddBcc("*****@*****.**"); message.From = new MailAddress("*****@*****.**", "Mission Platform Contact"); message.Html = "<html>" + messageText + "</html>"; message.Subject = "Initiative Enquiry"; var emailtransport = SendGridMail.Transport.Web.GetInstance(new NetworkCredential(GridMailUsername, GridMailPassword)); emailtransport.Deliver(message); } }
public abstract void TriggerCreating(DbxObject newobj, string type, Dictionary<string, object> properties, BlobDetails blob, string srcuid);
public DbxObject Create(string type, string srcuid, Dictionary<string, object> properties, BlobDetails blob = null) { // Create object return new DbxObject(this, type, properties, srcuid, blob); }
public void SetBlob(string srcuid, BlobDetails blob) { var request = HttpContext.Current.Request; // Check blob is present if (null == blob) throw new UserErrorException("parameter.missing", "Missing blob data"); // Check access var userLevel = UserLevel(srcuid); if (!AccessBlob(srcuid, false, true)) throw new UserErrorException("access.write", "Access violation attempt while write object (object level " + UserLevel(srcuid) + ")"); // Check data constraints if (Subschema.Blob.ContentTypes.Count > 0 && !Subschema.Blob.ContentTypes.ConvertAll(d => d.ToLower()).Contains(blob.ContentType.ToLower())) { var err = "This file type is not supported. The following types are supported: "; foreach (var type in Subschema.Blob.ContentTypes) err += type + ", "; throw new UserErrorException("blob.badtype", err.substr(0, -2)); } if (blob.Length < Subschema.Blob.MinSize) throw new UserErrorException("blob.toosmall", "File too small, must be at least " + Math.Round((double)Subschema.Blob.MinSize / 1024, 1) + "KB"); if (blob.Length > Subschema.Blob.MaxSize) throw new UserErrorException("blob.toolarge", "File too large, must be no more than " + Math.Round((double)Subschema.Blob.MaxSize / 1024, 1) + "KB"); // Open blob store var container = new BlobContainer(instance.Configuration.Object.Blob.ConnectionString, instance.Configuration.Object.Blob.Container); // Store file container.Get(magicUid).PutStreamCacheForever(blob.Stream, blob.Filename, blob.ContentType); //blobProps = store.GetProperties(magicUid); // Cache properties // Write Write(); // Return stream blob.Stream.Position = 0; }
public override object Execute() { var instance = Instances.Current; // Check inputs if (null == type) throw new UserErrorException("parameter.missing", "type; Required field missing"); if (null == properties) throw new UserErrorException("parameter.missing", "properties; Required field missing"); if (HttpContext.Current.Request.Files.Count > 1) throw new UserErrorException("parameter.invalid", "<data>; Multiple files in data"); SchemaType subschema; if (!instance.Configuration.Schema.Types.TryGetValue(type, out subschema)) { throw new UserErrorException("parameter.invalid", "type; Invalid value"); } // Iterate each key foreach (var prop in properties) { var pk = prop.Key; var pv = prop.Value; // Block spaces in property names if (pk.IndexOf(' ') > -1) throw new UserErrorException("parameter.invalid", "properties.[" + pk + "]; Property names cannot include spaces"); } // Check if blob present var blob = new BlobDetails(); var hasblob = true; var request = HttpContext.Current.Request; if (null == request) hasblob=false; if (request.Headers["X-File-Name"] == null && request.Files.Count < 1) hasblob = false; if (hasblob) { // Check for too many files if (request.Files.Count > 1) throw new UserErrorException("blob.multiple", "Multiple files in data"); // Select method if (request.Headers["X-File-Name"] == null) { // Form Method: Data passed as form (IE) try { // Locate file var file = request.Files[0]; blob.Filename = file.FileName; blob.ContentType = file.ContentType; blob.Stream = file.InputStream; blob.Length = file.ContentLength; // IE Hack HttpContext.Current.Response.ContentType = "text/html"; } catch (Exception ex) { throw new UserErrorException("blob.input", "File storage issue (Form Method)", ex); } } else { // Stream Method: Data passed as stream (Chrome, FFX, etc.) try { // Locate file blob.Filename = request.Headers["X-File-Name"]; blob.ContentType = Util.GetMimeType(blob.Filename); blob.Stream = request.InputStream; blob.Length = blob.Stream.Length; } catch (Exception ex) { throw new UserErrorException("blob.input", "File storage issue (Stream Method)", ex); } } } // Create object var obj = instance.Create(type, null == Session.Current.Uid ? "" : Session.Current.Uid, properties, blob); // Create Output var item = new Dictionary<string, object>(); // Get object try { item["object"] = obj.Output(Session.Current.Uid); item["result"] = "ok"; } catch (UnauthorizedAccessException) { item["result"] = "noaccess"; } catch (PropertyNotIndexedException) { item["result"] = "propertynotindexed"; } catch (PropertyNotExistsException) { item["result"] = "propertynotexist"; } return item; }