Ejemplo n.º 1
0
        // 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;
        }
Ejemplo n.º 2
0
        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");
            }
        }
Ejemplo n.º 3
0
        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);
            }
        }
Ejemplo n.º 4
0
 public abstract void TriggerCreating(DbxObject newobj, string type, Dictionary<string, object> properties, BlobDetails blob, string srcuid);
Ejemplo n.º 5
0
 public DbxObject Create(string type, string srcuid, Dictionary<string, object> properties, BlobDetails blob = null)
 {
     // Create object
     return new DbxObject(this, type, properties, srcuid, blob);
 }
Ejemplo n.º 6
0
        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;
        }
Ejemplo n.º 7
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;
        }