Esempio n. 1
0
        public Users(string dbUrl, string storageDir, string masterPassword) : base(dbUrl)
        {
            this.dbUrl          = dbUrl;
            this.masterPassword = masterPassword;

            var avatarDir = Path.Combine(storageDir, "avatar");

            if (!Dir.Exists(avatarDir))
            {
                Dir.CreateDirectory(avatarDir);
            }

            // API only available to authenticated users
            BeforeAsync = async(p, c) => await c.EnsureIsAuthenticatedAsync();

            // register a type
            Types["uid"] = (val) => (Regex.IsMatch(val, "^[A-Z0-9]+$")) ? val : null;

            GetAsync["/"] = async(p, c) =>
            {
                await RunBeforeAsync(null, c);

                var authUser = await c.GetAuthenticatedUserAsync();

                SqlFilter filterAuth;
                if (authUser.IsUser && c.Request.QueryString.ContainsKey("restrict"))
                {
                    filterAuth = User.GenerateFilterAuthUser(authUser);
                }
                else
                {
                    filterAuth = (new User()).FilterAuthUser(authUser);
                }
                using (DB db = await DB.CreateAsync(dbUrl))
                {
                    var result = await Model.SearchAsync <User>(db, c, filterAuth);

                    foreach (var item in result.Data)
                    {
                        await item.EnsureRightAsync(c, Right.Read, null);
                    }
                    c.Response.Content = result.ToJson(c);
                }
                c.Response.StatusCode = 200;
            };

            GetAsync["/current"] = async(p, c) =>
            {
                var user = await c.GetAuthenticatedUserAsync();

                if ((user == null) || !user.IsUser)
                {
                    c.Response.StatusCode = 401;
                }
                else
                {
                    c.Response.StatusCode          = 302;
                    c.Response.Headers["location"] = user.user.id;
                }
            };

            GetAsync["/current/isauthenticated"] = async(p, c) =>
            {
                var user = await c.GetAuthenticatedUserAsync();

                if (user == null)
                {
                    c.Response.StatusCode = 403;
                }
                else
                {
                    c.Response.StatusCode = 200;
                }
            };

            PostAsync["/{uid:uid}/upload/avatar"] = async(p, c) =>
            {
                var uid = (string)p["uid"];

                var oldUser = new User {
                    id = uid
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldUser.LoadAsync(db, true))
                    {
                        oldUser = null;
                    }
                }

                //var oldUser = await GetUserAsync(uid);
                if (oldUser == null)
                {
                    return;
                }

                await c.EnsureHasRightsOnUserAsync(oldUser, true, true, false);

                var           reader = c.Request.ReadAsMultipart();
                MultipartPart part;
                while ((part = await reader.ReadPartAsync()) != null)
                {
                    if (part.Headers.ContainsKey("content-disposition") && part.Headers.ContainsKey("content-type"))
                    {
                        if ((part.Headers["content-type"] != "image/jpeg") &&
                            (part.Headers["content-type"] != "image/png") &&
                            (part.Headers["content-type"] != "image/svg+xml"))
                        {
                            continue;
                        }

                        var disposition = ContentDisposition.Decode(part.Headers["content-disposition"]);
                        if (disposition.ContainsKey("name") && (disposition["name"] == "image"))
                        {
                            var dir = DirExt.CreateRecursive(Path.Combine(
                                                                 avatarDir, uid[0].ToString(), uid[1].ToString(), uid[2].ToString()));
                            var ext    = ".jpg";
                            var format = "jpeg";
                            //if ((part.Headers["content-type"] == "image/png") || (part.Headers["content-type"] == "image/svg+xml"))
                            //{
                            //	ext = ".png";
                            //	format = "png";
                            //}

                            var name = StringExt.RandomString(16) + "_" + uid + ext;

                            // crop / resize / convert the image using ImageMagick
                            var startInfo = new ProcessStartInfo("/usr/bin/convert", "- -auto-orient -strip -set option:distort:viewport \"%[fx:min(w,h)]x%[fx:min(w,h)]+%[fx:max((w-h)/2,0)]+%[fx:max((h-w)/2,0)]\" -distort SRT 0 +repage -quality 80 -resize 256x256 " + format + ":" + Path.Combine(dir.FullName, name));
                            startInfo.RedirectStandardOutput = false;
                            startInfo.RedirectStandardInput  = true;
                            startInfo.UseShellExecute        = false;
                            var process = new Process();
                            process.StartInfo = startInfo;
                            process.Start();

                            // read the file stream and send it to ImageMagick
                            await part.Stream.CopyToAsync(process.StandardInput.BaseStream);

                            process.StandardInput.Close();

                            process.WaitForExit();
                            process.Dispose();

                            c.Response.StatusCode = 200;
                            var userDiff = new User {
                                id = uid, avatar = name
                            };
                            using (DB db = await DB.CreateAsync(dbUrl))
                            {
                                await userDiff.UpdateAsync(db);

                                await userDiff.LoadAsync(db, true);
                            }
                            c.Response.Content = userDiff;

                            if ((oldUser.avatar != null) && (oldUser.avatar != "empty"))
                            {
                                var oldFile = Path.Combine(avatarDir, uid[0].ToString(), uid[1].ToString(), uid[2].ToString(), Path.GetFileName(oldUser.avatar));
                                if (File.Exists(oldFile))
                                {
                                    File.Delete(oldFile);
                                }
                            }
                        }
                    }
                }
            };

            GetAsync["/{uid:uid}/avatar"] = async(p, c) =>
            {
                var uid = (string)p["uid"];

                var user = new User {
                    id = uid
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await user.LoadAsync(db, true))
                    {
                        user = null;
                    }
                }

                if (user == null)
                {
                    return;
                }

                string avatarPath;
                if ((user.avatar == null) || (user.avatar == "empty"))
                {
                    if (user.gender == null)
                    {
                        avatarPath = "/avatar/avatar_neutre.svg";
                    }
                    else if (user.gender == Gender.M)
                    {
                        avatarPath = "/avatar/avatar_masculin.svg";
                    }
                    else
                    {
                        avatarPath = "/avatar/avatar_feminin.svg";
                    }
                }
                else
                {
                    avatarPath = "/api/avatar/user/" +
                                 uid.Substring(0, 1) + "/" + uid.Substring(1, 1) + "/" +
                                 uid.Substring(2, 1) + "/" + user.avatar;
                }

                c.Response.StatusCode          = 302;
                c.Response.Headers["location"] = avatarPath;
            };
        }
Esempio n. 2
0
        public Structures(string dbUrl, string storageDir) : base(dbUrl)
        {
            var structureDir = Path.Combine(storageDir, "structure");

            if (!Dir.Exists(structureDir))
            {
                Dir.CreateDirectory(structureDir);
            }

            // API only available to authenticated users
            BeforeAsync = async(p, c) => await c.EnsureIsAuthenticatedAsync();

            GetAsync["/{id}/subjects"] = async(p, c) =>
            {
                c.Response.StatusCode = 200;
                using (DB db = await DB.CreateAsync(dbUrl))
                    c.Response.Content = await db.SelectAsync <Grade>("SELECT * FROM subject WHERE id IN (SELECT `subject_id` FROM `group_user` WHERE `group_id` IN (SELECT id FROM `group` WHERE `structure_id`=?))", (string)p["id"]);
            };

            GetAsync["/{id}/image"] = async(p, c) =>
            {
                var id = (string)p["id"];

                var oldStructure = new Structure {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldStructure.LoadAsync(db, true))
                    {
                        oldStructure = null;
                    }
                }

                if (oldStructure == null)
                {
                    return;
                }

                var fullPath = Path.Combine(structureDir, $"{id}.jpg");

                if (File.Exists(fullPath))
                {
                    var shortName = Path.GetFileName(fullPath);
                    c.Response.Headers["content-type"] = "image/jpeg";

                    var    lastModif = File.GetLastWriteTime(fullPath);
                    string etag      = "\"" + lastModif.Ticks.ToString("X") + "\"";
                    c.Response.Headers["etag"] = etag;

                    if (c.Request.QueryString.ContainsKey("if-none-match") &&
                        (c.Request.QueryString["if-none-match"] == etag))
                    {
                        c.Response.StatusCode = 304;
                    }
                    else
                    {
                        c.Response.StatusCode    = 200;
                        c.Response.SupportRanges = true;
                        c.Response.Content       = new FileContent(fullPath);
                    }
                }
            };

            DeleteAsync["/{id}/image"] = async(p, c) =>
            {
                var id = (string)p["id"];

                var oldStructure = new Structure {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldStructure.LoadAsync(db, true))
                    {
                        oldStructure = null;
                    }
                }

                if (oldStructure == null)
                {
                    return;
                }

                await c.EnsureHasRightsOnStructureAsync(oldStructure, false, false, true);

                var fullPath = Path.Combine(structureDir, $"{id}.jpg");

                if (File.Exists(fullPath))
                {
                    File.Delete(fullPath);
                    c.Response.StatusCode = 200;
                    c.Response.Content    = "";
                }
            };

            PostAsync["/{id}/image"] = async(p, c) =>
            {
                var id = (string)p["id"];

                var oldStructure = new Structure {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldStructure.LoadAsync(db, true))
                    {
                        oldStructure = null;
                    }
                }

                if (oldStructure == null)
                {
                    return;
                }

                await c.EnsureHasRightsOnStructureAsync(oldStructure, false, false, true);

                var           reader = c.Request.ReadAsMultipart();
                MultipartPart part;
                while ((part = await reader.ReadPartAsync()) != null)
                {
                    if (part.Headers.ContainsKey("content-disposition") && part.Headers.ContainsKey("content-type"))
                    {
                        if ((part.Headers["content-type"] != "image/jpeg") &&
                            (part.Headers["content-type"] != "image/png") &&
                            (part.Headers["content-type"] != "image/svg+xml"))
                        {
                            continue;
                        }

                        var disposition = ContentDisposition.Decode(part.Headers["content-disposition"]);
                        if (disposition.ContainsKey("name") && (disposition["name"] == "image"))
                        {
                            var dir      = DirExt.CreateRecursive(structureDir);
                            var fullPath = Path.Combine(dir.FullName, $"{id}.jpg");

                            // crop / resize / convert the image using ImageMagick
                            var startInfo = new ProcessStartInfo("/usr/bin/convert", $"- -auto-orient -strip -distort SRT 0 +repage -quality 80 -resize 1024x1024 jpeg:{fullPath}");
                            startInfo.RedirectStandardOutput = false;
                            startInfo.RedirectStandardInput  = true;
                            startInfo.UseShellExecute        = false;
                            var process = new Process();
                            process.StartInfo = startInfo;
                            process.Start();

                            // read the file stream and send it to ImageMagick
                            await part.Stream.CopyToAsync(process.StandardInput.BaseStream);

                            process.StandardInput.Close();

                            process.WaitForExit();
                            process.Dispose();

                            c.Response.StatusCode = 200;
                        }
                    }
                }
            };
        }
Esempio n. 3
0
        public Resources(string dbUrl, string storageDir) : base(dbUrl)
        {
            var resourceDir = Path.Combine(storageDir, "resource");

            if (!Dir.Exists(resourceDir))
            {
                Dir.CreateDirectory(resourceDir);
            }

            GetAsync["/{id:int}/image"] = async(p, c) =>
            {
                var id = (int)p["id"];

                var oldResource = new Resource {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldResource.LoadAsync(db, true))
                    {
                        oldResource = null;
                    }
                }

                if (oldResource == null)
                {
                    return;
                }

                var fullPath = Path.Combine(resourceDir, $"{id}.jpg");

                if (File.Exists(fullPath))
                {
                    var shortName = Path.GetFileName(fullPath);
                    c.Response.Headers["content-type"] = "image/jpeg";

                    var    lastModif = File.GetLastWriteTime(fullPath);
                    string etag      = "\"" + lastModif.Ticks.ToString("X") + "\"";
                    c.Response.Headers["etag"] = etag;

                    if (c.Request.QueryString.ContainsKey("if-none-match") &&
                        (c.Request.QueryString["if-none-match"] == etag))
                    {
                        c.Response.StatusCode = 304;
                    }
                    else
                    {
                        c.Response.StatusCode    = 200;
                        c.Response.SupportRanges = true;
                        c.Response.Content       = new FileContent(fullPath);
                    }
                }
            };

            DeleteAsync["/{id:int}/image"] = async(p, c) =>
            {
                var id = (int)p["id"];

                var oldResource = new Resource {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldResource.LoadAsync(db, true))
                    {
                        oldResource = null;
                    }
                }

                if (oldResource == null)
                {
                    return;
                }

                var fullPath = Path.Combine(resourceDir, $"{id}.jpg");

                if (File.Exists(fullPath))
                {
                    File.Delete(fullPath);
                    c.Response.StatusCode = 200;
                    c.Response.Content    = "";
                }
            };

            PostAsync["/{id:int}/image"] = async(p, c) =>
            {
                var id = (int)p["id"];

                var oldResource = new Resource {
                    id = id
                };
                using (var db = await DB.CreateAsync(dbUrl))
                {
                    if (!await oldResource.LoadAsync(db, true))
                    {
                        oldResource = null;
                    }
                }

                if (oldResource == null)
                {
                    return;
                }

                var           reader = c.Request.ReadAsMultipart();
                MultipartPart part;
                while ((part = await reader.ReadPartAsync()) != null)
                {
                    if (part.Headers.ContainsKey("content-disposition") && part.Headers.ContainsKey("content-type"))
                    {
                        if ((part.Headers["content-type"] != "image/jpeg") &&
                            (part.Headers["content-type"] != "image/png") &&
                            (part.Headers["content-type"] != "image/svg+xml"))
                        {
                            continue;
                        }

                        var disposition = ContentDisposition.Decode(part.Headers["content-disposition"]);
                        if (disposition.ContainsKey("name") && (disposition["name"] == "image"))
                        {
                            var dir      = DirExt.CreateRecursive(resourceDir);
                            var fullPath = Path.Combine(dir.FullName, $"{id}.jpg");

                            // crop / resize / convert the image using ImageMagick
                            var startInfo = new ProcessStartInfo("/usr/bin/convert", $"- -auto-orient -strip -distort SRT 0 +repage -quality 80 -resize 1024x1024 jpeg:{fullPath}");
                            startInfo.RedirectStandardOutput = false;
                            startInfo.RedirectStandardInput  = true;
                            startInfo.UseShellExecute        = false;
                            var process = new Process();
                            process.StartInfo = startInfo;
                            process.Start();

                            // read the file stream and send it to ImageMagick
                            await part.Stream.CopyToAsync(process.StandardInput.BaseStream);

                            process.StandardInput.Close();

                            process.WaitForExit();
                            process.Dispose();

                            c.Response.StatusCode = 200;
                        }
                    }
                }
            };
        }