コード例 #1
0
ファイル: Lecturers.cs プロジェクト: Wroud/ScheduleReact
 public async Task <ActionResult> FindByFullName(string name)
 {
     return(Json(JsonQuery.Create(true).Result(
                     data: await DbContext.Lecturers.Where(l =>
                                                           Regex.IsMatch(l.FullName, name, RegexOptions.IgnoreCase | RegexOptions.Multiline))
                     .ToArrayAsync())));
 }
コード例 #2
0
ファイル: Lecturers.cs プロジェクト: Wroud/ScheduleReact
        public async Task <ActionResult> GetLecturer(string id)
        {
            var res = new JsonQuery(true);

            if (!await DbContext.Lecturers.AnyAsync(l => l.Id == id))
            {
                res.AddError(null, "query", "Лектор не найден");
            }
            return(Json(res.Result(data: await DbContext.Lecturers.FirstOrDefaultAsync(l => l.Id == id))));
        }
コード例 #3
0
ファイル: Lecturers.cs プロジェクト: Wroud/ScheduleReact
        public async Task <IActionResult> GetLecturers()
        {
            var lecturers = await DbContext.Lecturers.ToListAsync();

            // for (int i = 0; i < 1000; i++) {
            //     lecturers.Add (new Lecturer () {
            //         Id = Guid.NewGuid ().ToString (),
            //         FirstName = $"Lecturer {i}",
            //     });
            // }
            return(Json(JsonQuery.Create(true).Result(data: lecturers)));
        }
コード例 #4
0
        public ActionResult Index()
        {
            var owner = Deserialize.FromJson(JsonData);

            var model = new HomeModel()
            {
                CatsOfMales   = JsonQuery.GetAnimalNamesByGender(owner, "Male", "Cat"),
                CatsOfFemales = JsonQuery.GetAnimalNamesByGender(owner, "Female", "Cat")
            };

            return(View(model));
        }
コード例 #5
0
ファイル: QueryInsert.cs プロジェクト: ECN-Lab/Rose.Server
        public QueryInsert(Execute.Executer executer, JObject query)
            : base(executer, query)
        {
            //  data 절
            JToken dataToken = JsonQuery.GetProperty("data").Value;

            if (dataToken is JValue)
            {
                string data = (string)dataToken;
                if (data.Length > 0 && data[0] == '@')
                {
                    List <DataObject> resultSet;
                    if (ParentExecuter.ResultSets.TryGetValue(data, out resultSet) == false)
                    {
                        throw new AegisException(RoseResult.InvalidArgument, $"{data} is not exist name.");
                    }


                    foreach (var item in resultSet)
                    {
                        Data.Add(JObject.Parse(item.Data));
                    }
                }
                else
                {
                    throw new AegisException(RoseResult.InvalidArgument, $"{data} is not valid name.");
                }
            }
            else if (dataToken is JObject)
            {
                Data.Add(dataToken);
            }
            else if (dataToken is JArray)
            {
                foreach (var item in dataToken)
                {
                    Data.Add(item);
                }
            }


            UniqueFor   = (string)JsonQuery.GetProperty("uniqueFor", false)?.Value ?? null;
            OnDuplicate = (string)JsonQuery.GetProperty("onDuplicate", false)?.Value ?? null;
            if (OnDuplicate == null)
            {
                OnDuplicate = "ignore";
            }

            if (OnDuplicate != "ignore" && OnDuplicate != "update")
            {
                throw new AegisException(RoseResult.InvalidArgument, "onDuplicate value must be 'ignore' or 'update'.");
            }
        }
コード例 #6
0
        public string ToQuery(bool supportsSearch)
        {
            var queries = new List <string>();

            if (Skip.HasValue)
            {
                queries.Add($"$skip={Skip.Value}");
            }

            if (Top.HasValue)
            {
                queries.Add($"$top={Top.Value}");
            }

            if (!string.IsNullOrWhiteSpace(OrderBy))
            {
                queries.Add($"$orderby={OrderBy}");
            }

            if (JsonQuery != null)
            {
                queries.Add($"q={JsonQuery.ToJson()}");
            }

            if (Ids != null && Ids.Count > 0)
            {
                queries.Add($"ids={string.Join(",", Ids)}");
            }

            if (!string.IsNullOrWhiteSpace(Search))
            {
                if (!supportsSearch)
                {
                    throw new NotSupportedException("Full text search is not supported.");
                }

                queries.Add($"$search=\"{Search}\"");
            }
            else if (!string.IsNullOrWhiteSpace(Filter))
            {
                queries.Add($"$filter={Filter}");
            }

            var queryString = string.Join("&", queries);

            if (!string.IsNullOrWhiteSpace(queryString))
            {
                queryString = "?" + queryString;
            }

            return(queryString);
        }
コード例 #7
0
ファイル: Lecturers.cs プロジェクト: Wroud/ScheduleReact
        public async Task <ActionResult> Delete(string id)
        {
            var res = new JsonQuery(true);

            if (!await DbContext.Lecturers.AnyAsync(l => l.Id == id))
            {
                res.AddError(null, "query", "Лектор не найден");
            }
            DbContext.Lecturers.Remove(DbContext.Lecturers.FirstOrDefault(l => l.Id == id));
            await DbContext.SaveChangesAsync();

            return(Json(res.Result()));
        }
コード例 #8
0
        public QueryUpdate(Execute.Executer executer, JObject query)
            : base(executer, query)
        {
            //  data 절
            JToken dataToken = JsonQuery.GetProperty("data").Value;

            if (dataToken is JValue)
            {
                string data = (string)dataToken;
                if (data.Length > 0 && data[0] == '@')
                {
                    List <DataObject> resultSet;
                    if (ParentExecuter.ResultSets.TryGetValue(data, out resultSet) == false)
                    {
                        throw new AegisException(RoseResult.InvalidArgument, $"{data} is not exist name.");
                    }


                    if (resultSet.Count() > 1)
                    {
                        JArray arr = new JArray();
                        foreach (var item in resultSet)
                        {
                            arr.Add(JObject.Parse(item.Data));
                        }
                        Data = arr;
                    }
                    else if (resultSet.Count() == 1)
                    {
                        Data = JObject.Parse(resultSet.First().Data);
                    }
                    else
                    {
                        Data = JArray.Parse("[]");
                    }
                }
                else
                {
                    throw new AegisException(RoseResult.InvalidArgument, $"{data} is not valid name.");
                }
            }
            else if (dataToken is JObject)
            {
                Data = dataToken;
            }
            else if (dataToken is JArray)
            {
                Data = dataToken.DeepClone();
            }
        }
コード例 #9
0
ファイル: Lecturers.cs プロジェクト: Wroud/ScheduleReact
        public async Task <ActionResult> AddOrEdit(Lecturer model)
        {
            var res = new JsonQuery(true);

            res.Parse(ModelState);
            if (ModelState.IsValid)
            {
                Lecturer current;
                if (!string.IsNullOrWhiteSpace(model.Id))
                {
                    if (!await DbContext.Lecturers.AnyAsync(l => l.Id == model.Id))
                    {
                        res.AddError(null, "FirstName", "Лектор не найден");
                        goto res;
                    }
                    DbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
                    current = await DbContext.Lecturers.FirstOrDefaultAsync(l => l.Id == model.Id);

                    var find = await DbContext.Lecturers.FirstOrDefaultAsync(l =>
                                                                             l.FirstName == model.FirstName &&
                                                                             l.SecondName == model.SecondName &&
                                                                             l.LastName == model.LastName);

                    if (find != null && find.Id != current.Id)
                    {
                        res.AddError(null, "FirstName", "Лектор с таким именем фамилией и отчеством уже есть.");
                        goto res;
                    }
                    DbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
                    DbContext.Update(model);
                }
                else
                {
                    if (await DbContext.Lecturers.AnyAsync(l =>
                                                           l.FirstName == model.FirstName &&
                                                           l.SecondName == model.SecondName &&
                                                           l.LastName == model.LastName))
                    {
                        res.AddError(null, "FirstName", "Лектор с таким именем фамилией и отчеством уже есть.");
                        goto res;
                    }

                    await DbContext.Lecturers.AddAsync(model);
                }
                await DbContext.SaveChangesAsync();
            }
res:
            return(Json(res.Result(data: model)));
        }
コード例 #10
0
ファイル: QueryDto.cs プロジェクト: SpyRefused/chthonianex
        public Q ToQuery()
        {
            var result = Q.Empty;

            if (Ids != null)
            {
                result = result.WithIds(Ids);
            }

            if (OData != null)
            {
                result = result.WithODataQuery(OData);
            }

            if (JsonQuery != null)
            {
                result = result.WithJsonQuery(JsonQuery.ToString());
            }

            return(result);
        }
コード例 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ProtectedUsersAndAuthentication"/> class.
        /// </summary>
        /// <param name="accessRepo">Supplied through DI.</param>
        /// <param name="signUpRepo">Supplied through DI.</param>
        /// <param name="personRepo">Supplied through DI.</param>
        /// <param name="env">Supplied through DI.</param>
        /// <param name="date">Supplied through DI.</param>
        public ProtectedUsersAndAuthentication(
            IRepository <AccessTokenSchema> accessRepo,
            IRepository <SignUpTokenSchema> signUpRepo,
            IRepository <PersonSchema> personRepo,
            IAppEnvironment env,
            IDateExtra date)
            : base("/")
        {
            this.Before += PreSecurity.CheckAccess(accessRepo, date);

            this.Get <GetUser>("users/{id}/", async(req, res) =>
            {
                string userID = req.RouteValues.As <string>("id");
                var person    = await personRepo.FindById(userID);

                if (person == null || !person.IsExisting)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                // Has to exit due to pre-security check
                string token    = req.Cookies["ExperienceCapture-Access-Token"];
                var accessToken = await accessRepo.FindOne(
                    Builders <AccessTokenSchema>
                    .Filter
                    .Where(a => a.Hash == PasswordHasher.Hash(token)));

                if (person.InternalId != accessToken.User && accessToken.Role != RoleOptions.Admin)
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                string json = JsonQuery.FulfilEncoding(req.Query, person);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                person.InternalId = null;

                await res.FromBson(person);
            });

            this.Delete <DeleteUser>("users/{id}/", async(req, res) =>
            {
                string userID = req.RouteValues.As <string>("id");
                var person    = await personRepo.FindById(userID);

                if (person == null)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                // Has to exit due to pre-security check
                string token     = req.Cookies["ExperienceCapture-Access-Token"];
                var accessFilter = Builders <AccessTokenSchema>
                                   .Filter
                                   .Where(a => a.Hash == PasswordHasher.Hash(token));
                var accessToken = await accessRepo.FindOne(accessFilter);

                // Check if the user being requested is the same
                // As the one requesting, unless they have the admin role
                if (person.InternalId != accessToken.User && accessToken.Role != RoleOptions.Admin)
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                var filter = Builders <PersonSchema> .Filter
                             .Where(p => p.Id == userID);

                var update = Builders <PersonSchema> .Update
                             .Set(p => p.IsExisting, false);

                await personRepo.Update(filter, update);

                await res.FromString();
            });

            this.Post <PostSignUp>("authentication/signUps", async(req, res) =>
            {
                string newToken = Generate.GetRandomToken();

                var tokenDoc = new SignUpTokenSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Hash       = PasswordHasher.Hash(newToken),
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                };

                await signUpRepo.Add(tokenDoc);

                var responce = new SignUpTokenResponce
                {
                    SignUpToken = newToken,
                    Expiration  = TimerExtra.ProjectSeconds(date, tokenDoc.ExpirationSeconds),
                };
                var responceDoc = responce.ToBsonDocument();

                string json = JsonQuery.FulfilEncoding(req.Query, responceDoc);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(responceDoc);
            });
        }
コード例 #12
0
        /// <summary>
        /// 打印装车单信息查询
        /// </summary>
        /// <param name="vhTrainNo"></param>
        /// <returns></returns>
        public List <OrderSortDetailPrintEntity> Query(string vhTrainNo)
        {
            List <OrderSortDetailPrintEntity> list = new List <OrderSortDetailPrintEntity>();

            try
            {
                #region 请求数据
                System.Text.StringBuilder loStr = new System.Text.StringBuilder();
                loStr.Append("vhTrainNo=").Append(vhTrainNo).Append("&");
                loStr.Append("warehouseType=").Append(EUtilStroreType.WarehouseTypeToInt(GlobeSettings.LoginedUser.WarehouseType));
                string jsonQuery = WebWork.SendRequest(loStr.ToString(), WebWork.URL_Query);
                if (string.IsNullOrEmpty(jsonQuery))
                {
                    MsgBox.Warn(WebWork.RESULT_NULL);
                    //LogHelper.InfoLog(WebWork.RESULT_NULL);
                    return(list);
                }
                #endregion

                #region 正常错误处理

                JsonQuery bill = JsonConvert.DeserializeObject <JsonQuery>(jsonQuery);
                if (bill == null)
                {
                    MsgBox.Warn(WebWork.JSON_DATA_NULL);
                    return(list);
                }
                if (bill.flag != 0)
                {
                    MsgBox.Warn(bill.error);
                    return(list);
                }
                #endregion

                #region 赋值数据
                foreach (JsonQueryResult jbr in bill.result)
                {
                    OrderSortDetailPrintEntity asnEntity = new OrderSortDetailPrintEntity();
                    asnEntity.BillID          = Convert.ToInt32(jbr.billId);
                    asnEntity.BillNo          = jbr.billNo;
                    asnEntity.BillRemark      = jbr.wmsRemark;
                    asnEntity.CustomerAddress = jbr.address;
                    asnEntity.CustomerName    = jbr.cName;
                    asnEntity.FullCount       = Convert.ToInt32(jbr.fullCount);
                    asnEntity.OrderSort       = Convert.ToInt32(jbr.inVhSort);
                    asnEntity.Warehouse       = jbr.whName;
                    //try
                    //{
                    //    if (!string.IsNullOrEmpty(jbr.closeDate))
                    //        asnEntity.CloseDate = Convert.ToDateTime(jbr.closeDate);
                    //    if (!string.IsNullOrEmpty(jbr.printedTime))
                    //        asnEntity.PrintedTime = Convert.ToDateTime(jbr.printedTime);
                    //    if (!string.IsNullOrEmpty(jbr.createDate))
                    //        asnEntity.CreateDate = Convert.ToDateTime(jbr.createDate);
                    //}
                    //catch (Exception msg)
                    //{
                    //    LogHelper.errorLog("FrmVehicle+QueryNotRelatedBills", msg);
                    //}
                    list.Add(asnEntity);
                }
                return(list);

                #endregion
            }
            catch (Exception ex)
            {
                MsgBox.Err(ex.Message);
            }
            return(list);
        }
コード例 #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="UsersAndAuthentication"/> class.
        /// </summary>
        /// <param name="accessRepo">Supplied through DI.</param>
        /// <param name="signUpRepo">Supplied through DI.</param>
        /// <param name="claimRepo">Supplied through DI.</param>
        /// <param name="personRepo">Supplied through DI.</param>
        /// <param name="env">Supplied through DI.</param>
        /// <param name="date">Supplied through DI.</param>
        public UsersAndAuthentication(
            IRepository <AccessTokenSchema> accessRepo,
            IRepository <SignUpTokenSchema> signUpRepo,
            IRepository <ClaimTokenSchema> claimRepo,
            IRepository <PersonSchema> personRepo,
            IAppEnvironment env,
            IDateExtra date)
            : base("/")
        {
            this.Post <PostUsers>("users", async(req, res) =>
            {
                var newPerson = await req.BindAndValidate <PersonRequest>();

                if (!newPerson.ValidationResult.IsValid)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                var person = await GoogleApi.ValidateUser(newPerson.Data.idToken, env);
                if (person == null)
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                var filter = Builders <SignUpTokenSchema>
                             .Filter
                             .Where(t => t.Hash == PasswordHasher.Hash(newPerson.Data.signUpToken));

                var signUpDoc = await signUpRepo.FindOne(filter);

                if (signUpDoc == null || signUpDoc.CreatedAt.IsAfter(date, signUpDoc.ExpirationSeconds))
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                if (!signUpDoc.IsExisting)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                var update = Builders <SignUpTokenSchema> .Update
                             .Set(s => s.IsExisting, false);

                var existingPerson = await personRepo.FindById(person.Subject);

                // Check if the person already exists
                if (existingPerson != null)
                {
                    // Recreate them if they where deleted
                    if (!existingPerson.IsExisting)
                    {
                        var filterPerson = Builders <PersonSchema> .Filter
                                           .Where(p => p.Id == person.Subject);

                        var updatePerson = Builders <PersonSchema> .Update
                                           .Set(p => p.IsExisting, true);

                        await personRepo.Update(filterPerson, updatePerson);
                        await signUpRepo.Update(filter, update);

                        await res.FromString();
                    }
                    else
                    {
                        // Return error is they really exist
                        res.StatusCode = Status409Conflict;
                    }

                    return;
                }

                var personObject = new PersonSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Id         = person.Subject,
                    Fullname   = person.Name,
                    Firstname  = person.GivenName,
                    Lastname   = person.FamilyName,
                    Email      = person.Email,
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                    Role       = signUpDoc.Role,
                };

                await personRepo.Add(personObject);
                await signUpRepo.Update(filter, update);

                await res.FromString();
            });

            // Due to a bug with adding multiple routes of the same path
            // Path in different modules, we manual auth here
            this.Get <GetUsers>("users", async(req, res) =>
            {
                var isAllowed = await PreSecurity.CheckAccessDirectly(req, res, accessRepo, date, RoleOptions.Admin);

                if (!isAllowed)
                {
                    return;
                }

                var filter = Builders <PersonSchema> .Filter
                             .Where(p => p.IsExisting == true);

                var sorter = Builders <PersonSchema> .Sort
                             .Descending(p => p.Fullname);

                var persons = await personRepo.FindAll(filter, sorter);

                var personsWithoutId = persons.Select((p) =>
                {
                    p.InternalId = null;
                    return(p);
                });

                var responceBody = new PersonsResponce
                {
                    ContentList = new List <PersonSchema>(personsWithoutId),
                };

                string json = JsonQuery.FulfilEncoding(req.Query, responceBody);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(responceBody);
            });

            this.Post <PostAccessToken>("users/{id}/tokens/", async(req, res) =>
            {
                string userID = req.RouteValues.As <string>("id");
                var userDoc   = await personRepo.FindById(userID);

                if (userDoc == null || !userDoc.IsExisting)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                var newAccessRequest = await req.BindAndValidate <AccessTokenRequest>();
                if (!newAccessRequest.ValidationResult.IsValid)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                var person = await GoogleApi.ValidateUser(newAccessRequest.Data.idToken, env);
                if (person == null)
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                if (person.Subject != userID)
                {
                    res.StatusCode = Status409Conflict;
                    return;
                }

                string newToken = Generate.GetRandomToken();
                string newHash  = PasswordHasher.Hash(newToken);

                var tokenObject = new AccessTokenSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Hash       = newHash,
                    User       = userDoc.InternalId,
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                    Role       = userDoc.Role,
                };

                await accessRepo.Add(tokenObject);

                if (newAccessRequest.Data.claimToken != null)
                {
                    var filterClaims = Builders <ClaimTokenSchema> .Filter
                                       .Where(c => c.Hash == PasswordHasher.Hash(newAccessRequest.Data.claimToken));

                    var claimDoc = await claimRepo.FindOne(filterClaims);

                    // 401 returned twice, which may be hard for the client to interpret
                    if (claimDoc == null || claimDoc.CreatedAt.IsAfter(date, claimDoc.ExpirationSeconds))
                    {
                        res.StatusCode = Status401Unauthorized;
                        return;
                    }

                    // Don't allow overwriting an access token
                    if (claimDoc.Access == null && claimDoc.IsExisting)
                    {
                        var update = Builders <ClaimTokenSchema> .Update
                                     .Set(c => c.Access, tokenObject.InternalId)
                            #pragma warning disable SA1515
                                     // Unfortunately claim access tokens have to be saved to the database
                                     // So that state can be communicated between clients
                            #pragma warning restore SA1515
                                     .Set(c => c.AccessToken, newToken);

                        await claimRepo.Update(filterClaims, update);
                    }

                    await res.FromString();
                }
                else
                {
                    var responce = new AccessTokenResponce
                    {
                        AccessToken = newToken,
                        Expiration  = TimerExtra.ProjectSeconds(date, tokenObject.ExpirationSeconds),
                    };

                    string json = JsonQuery.FulfilEncoding(req.Query, responce);
                    if (json != null)
                    {
                        await res.FromJson(json);
                        return;
                    }

                    await res.FromBson(responce.ToBsonDocument());
                }
            });

            this.Post <PostClaims>("authentication/claims/", async(req, res) =>
            {
                string newToken = Generate.GetRandomToken();
                string newHash  = PasswordHasher.Hash(newToken);

                var tokenDoc = new ClaimTokenSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Hash       = newHash,
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                };

                await claimRepo.Add(tokenDoc);

                var responce = new ClaimTokenResponce
                {
                    ClaimToken = newToken,
                    Expiration = TimerExtra.ProjectSeconds(date, tokenDoc.ExpirationSeconds),
                };

                string json = JsonQuery.FulfilEncoding(req.Query, responce);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(responce.ToBsonDocument());
            });

            this.Get <GetClaims>("authentication/claims/", async(req, res) =>
            {
                string claimToken = req.Cookies["ExperienceCapture-Claim-Token"];
                if (claimToken == null)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                var filter = Builders <ClaimTokenSchema> .Filter
                             .Where(c => c.Hash == PasswordHasher.Hash(claimToken));
                var claimDoc = await claimRepo.FindOne(filter);

                if (claimDoc == null)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                if (!claimDoc.IsExisting || claimDoc.CreatedAt.IsAfter(date, claimDoc.ExpirationSeconds))
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                if (claimDoc.Access == null)
                {
                    res.StatusCode = Status202Accepted;
                    await res.FromString("PENDING");
                    return;
                }

                var update = Builders <ClaimTokenSchema> .Update
                             .Set(c => c.IsExisting, false)
                    #pragma warning disable SA1515
                             // Removes the access token from the database
                             // Important to increase security
                    #pragma warning restore SA1515
                             .Set(c => c.AccessToken, null);

                await claimRepo.Update(filter, update);

                var responce = new AccessTokenResponce
                {
                    AccessToken = claimDoc.AccessToken,
                    Expiration  = TimerExtra.ProjectSeconds(date, claimDoc.ExpirationSeconds),
                };

                string json = JsonQuery.FulfilEncoding(req.Query, responce);
                if (json != null)
                {
                    await res.FromString(json);
                    return;
                }

                await res.FromBson(responce.ToBsonDocument());
            });

            this.Post <PostAdmin>("authentication/admins/", async(req, res) =>
            {
                var newAdmin = await req.BindAndValidate <AdminPasswordRequest>();
                if (!newAdmin.ValidationResult.IsValid)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                if (!PasswordHasher.Check(newAdmin.Data.password, env.PasswordHash) && env.SkipValidation != "true")
                {
                    res.StatusCode = Status401Unauthorized;
                    return;
                }

                string newToken = Generate.GetRandomToken();

                var tokenDoc = new SignUpTokenSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Hash       = PasswordHasher.Hash(newToken),
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                    Role       = RoleOptions.Admin,
                };

                await signUpRepo.Add(tokenDoc);

                var responce = new SignUpTokenResponce
                {
                    SignUpToken = newToken,
                    Expiration  = TimerExtra.ProjectSeconds(date, tokenDoc.ExpirationSeconds),
                };

                string json = JsonQuery.FulfilEncoding(req.Query, responce);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(responce.ToBsonDocument());
            });
        }
コード例 #14
0
ファイル: QuerySelect.cs プロジェクト: ECN-Lab/Rose.Server
        public QuerySelect(Execute.Executer executer, JObject query)
            : base(executer, query)
        {
            //  sortKey 절
            var sortKey = JsonQuery.GetProperty("sortKey", false)?.Value;

            if (sortKey != null)
            {
                if (sortKey is JValue)
                {
                    var item = ((string)sortKey).Split(' ');
                    if (item.Count() == 0 || item.Count() > 2)
                    {
                        throw new AegisException(RoseResult.InvalidArgument, "'sortKey' is must have one or two arguments.");
                    }

                    string orderBy = (item.Count() >= 2 ? item[1] : "asc");
                    if (orderBy != "asc" && orderBy != "desc")
                    {
                        throw new AegisException(RoseResult.InvalidArgument, $"'orderBy' is must be 'asc' or 'desc'.");
                    }

                    SortKeys    = new SortKey[1];
                    SortKeys[0] = new SortKey()
                    {
                        Key     = item[0],
                        OrderBy = orderBy
                    };
                }
                else if (sortKey is JArray)
                {
                    int index = 0;
                    SortKeys = new SortKey[sortKey.Count()];

                    foreach (var key in sortKey)
                    {
                        var item = ((string)key).Split(' ');
                        if (item.Count() == 0 || item.Count() > 2)
                        {
                            throw new AegisException(RoseResult.InvalidArgument, "'sortKey' is must have one or two arguments.");
                        }

                        string orderBy = (item.Count() >= 2 ? item[1] : "asc");
                        if (orderBy != "asc" && orderBy != "desc")
                        {
                            throw new AegisException(RoseResult.InvalidArgument, $"'orderBy' is must be 'asc' or 'desc'.");
                        }

                        SortKeys[index++] = new SortKey()
                        {
                            Key     = item[0],
                            OrderBy = orderBy
                        };
                    }
                }
            }


            //  range 절
            var range = JsonQuery.GetProperty("range", false)?.Value as JArray;

            if (range != null)
            {
                if (range.Count() != 2)
                {
                    throw new AegisException(RoseResult.InvalidArgument, $"'range' is must have two arguments.");
                }

                RangeStart = range.ElementAt(0).ToString().ToInt32();
                RangeCount = range.ElementAt(1).ToString().ToInt32();
                if (RangeStart < 0 || RangeCount < 0)
                {
                    throw new AegisException(RoseResult.InvalidArgument, $"Argument of 'range' is not valid.");
                }
            }
            else
            {
                RangeStart = -1;
                RangeCount = -1;
            }
        }
コード例 #15
0
 protected void btnCreateTree_Click(object sender, EventArgs e)
 {
     var root = new JsonQuery().GetJsonTree(txtJson.Text);
     literalOutput.Text = JsonConvert.SerializeObject(root, Formatting.Indented);
 }
コード例 #16
0
 protected void btnGetData_Click(object sender, EventArgs e)
 {
     var data = new JsonQuery().GetDataFromPath(txtJson.Text, txtPath.Text);
     literalOutput.Text = JsonConvert.SerializeObject(data);
 }
コード例 #17
0
ファイル: Sessions.cs プロジェクト: jhburns/ExperienceCapture
        /// <summary>
        /// Initializes a new instance of the <see cref="Sessions"/> class.
        /// </summary>
        /// <param name="accessRepo">Supplied through DI.</param>
        /// <param name="sessionRepo">Supplied through DI.</param>
        /// <param name="personRepo">Supplied through DI.</param>
        /// <param name="captureRepo">Supplied through DI.</param>
        /// <param name="logger">Supplied through DI.</param>
        /// <param name="date">Supplied through DI.</param>
        public Sessions(
            IRepository <AccessTokenSchema> accessRepo,
            IRepository <SessionSchema> sessionRepo,
            IRepository <PersonSchema> personRepo,
            IRepository <BsonDocument> captureRepo,
            ILogger logger,
            IDateExtra date)
            : base("/sessions")
        {
            this.Before += PreSecurity.CheckAccess(accessRepo, date);

            this.Post <PostSessions>("/", async(req, res) =>
            {
                // Has to exist due to PreSecurity Check
                string token = req.Cookies["ExperienceCapture-Access-Token"];

                var accessTokenDoc = await accessRepo.FindOne(
                    Builders <AccessTokenSchema>
                    .Filter
                    .Where(a => a.Hash == PasswordHasher.Hash(token)));

                var filterUser = Builders <PersonSchema> .Filter.Where(p => p.InternalId == accessTokenDoc.User);

                var user = await personRepo
                           .FindOne(filterUser);

                string shortID = Generate.GetRandomId(4);

                var sessionDoc = new SessionSchema
                {
                    InternalId = ObjectId.GenerateNewId(),
                    Id         = shortID,
                    User       = user, // Copying user data instead of referencing so it can never change in the session
                    CreatedAt  = new BsonDateTime(date.UtcNow),
                    Tags       = new List <string>(),
                };

                // Retry generating a short id until it is unique
                bool isUnique = true;
                do
                {
                    try
                    {
                        sessionDoc.Id = shortID;
                        await sessionRepo.Add(sessionDoc);
                        isUnique = true;
                    }
                    catch (MongoWriteException e)
                    {
                        // Re-throw any other type of exception except non-unique keys
                        if (e.WriteError.Code != 11000)
                        {
                            throw e;
                        }

                        shortID  = Generate.GetRandomId(4);
                        isUnique = false;
                    }
                }while (!isUnique);

                // isOngoing is a proxy variable and will always start out as true
                sessionDoc.IsOngoing       = true;
                sessionDoc.InternalId      = null;
                sessionDoc.User.InternalId = null;

                captureRepo.Configure($"sessions.{shortID}");

                // Secondary index or else Mongo will fail on large queries
                // It has a limit for max number of documents on properties
                // Without an index, see https://docs.mongodb.com/manual/reference/limits/#Sort-Operations
                var index = Builders <BsonDocument> .IndexKeys;
                var key   = index.Ascending("frameInfo.realtimeSinceStartup");

                await captureRepo.Index(key);

                string json = JsonQuery.FulfilEncoding(req.Query, sessionDoc);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(sessionDoc);
            });

            this.Get <GetSessions>("/", async(req, res) =>
            {
                var builder = Builders <SessionSchema> .Filter;

                // Note: only use `&=` for adding to the filter,
                // Or else the filter cannot handle multiple query string options
                FilterDefinition <SessionSchema> filter = builder.Empty;

                var startMin = new BsonDateTime(date.UtcNow.AddSeconds(-300)); // 5 minutes
                var closeMin = new BsonDateTime(date.UtcNow.AddSeconds(-5));   // 5 seconds

                var hasTags = req.Query.AsMultiple <string>("hasTags").ToList();
                if (hasTags.Count > 0)
                {
                    foreach (var tag in hasTags)
                    {
                        filter &= builder.Where(s => s.Tags.Contains(tag));
                    }
                }

                var lacksTags = req.Query.AsMultiple <string>("lacksTags").ToList();
                if (lacksTags.Count > 0)
                {
                    foreach (var tag in lacksTags)
                    {
                        filter &= builder.Where(s => !s.Tags.Contains(tag));
                    }
                }

                // Three potential options: null, true, or false
                if (req.Query.As <bool?>("isOngoing") != null)
                {
                    bool isOngoing = req.Query.As <bool>("isOngoing");

                    if (isOngoing)
                    {
                        filter &= builder.Where(s => s.IsOpen == true)
                                  & ((builder.Eq(s => s.LastCaptureAt, BsonNull.Value)
                                      & builder.Where(s => s.CreatedAt > startMin))
                                     | (builder.Eq(s => s.LastCaptureAt, BsonNull.Value)
                                        & builder.Where(s => s.LastCaptureAt > closeMin)));
                    }
                    else
                    {
                        filter &= builder.Where(s => s.IsOpen == false)
                                  | ((builder.Eq(s => s.LastCaptureAt, BsonNull.Value)
                                      & builder.Where(s => s.CreatedAt < startMin))
                                     | (builder.Eq(s => s.LastCaptureAt, BsonNull.Value)
                                        & builder.Where(s => s.LastCaptureAt < closeMin)));
                    }
                }

                var page = req.Query.As <int?>("page") ?? 1;
                if (page < 1)
                {
                    // Page query needs to be possible
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                var direction = req.Query.As <string>("sort");
                SortDefinition <SessionSchema> sorter;
                if (direction == null)
                {
                    sorter = Builders <SessionSchema> .Sort.Descending(s => s.CreatedAt);
                }
                else
                {
                    if (Enum.TryParse(typeof(SortOptions), direction, true, out object options))
                    {
                        sorter = ((SortOptions)options).ToDefinition();
                    }
                    else
                    {
                        res.StatusCode = Status400BadRequest;
                        return;
                    }
                }

                var sessionDocs = await sessionRepo
                                  .FindAll(filter, sorter, page);

                var sessionsDocsWithOngoing = sessionDocs.Select((s) =>
                {
                    bool isStarted = false;
                    if (s.LastCaptureAt != BsonNull.Value)
                    {
                        isStarted = true;
                    }

                    bool isOngoing;
                    if (s.IsOpen)
                    {
                        isOngoing = (!isStarted &&
                                     startMin < s.CreatedAt) ||
                                    (isStarted &&
                                     closeMin < s.LastCaptureAt);
                    }
                    else
                    {
                        isOngoing = false;
                    }

                    s.IsOngoing       = isOngoing;
                    s.InternalId      = null;
                    s.User.InternalId = null;

                    return(s);
                });

                var count        = await sessionRepo.FindThenCount(filter);
                var clientValues = new SessionsResponce
                {
                    // Bson documents can't start with an array like Json, so a wrapping object is used instead
                    ContentList = sessionsDocsWithOngoing.ToList(),
                    PageTotal   = (long)Math.Ceiling((double)count / 10d),
                };

                string json = JsonQuery.FulfilEncoding(req.Query, clientValues);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(clientValues);
            });

            this.Post <PostSession>("/{id}", async(req, res) =>
            {
                string shortID = req.RouteValues.As <string>("id");

                var sessionDoc = await sessionRepo
                                 .FindById(shortID);

                if (sessionDoc == null)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                if (!sessionDoc.IsOpen)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                BsonDocument document;
                if (JsonQuery.CheckDecoding(req.Query))
                {
                    using (var ms = new MemoryStream())
                    {
                        await req.Body.CopyToAsync(ms);
                        ms.Position = 0;

                        try
                        {
                            document = BsonSerializer.Deserialize <BsonDocument>(ms);
                        }
                        catch (Exception err)
                        {
                            logger.LogError(err.Message);
                            res.StatusCode = Status400BadRequest;
                            return;
                        }
                    }
                }
                else
                {
                    string json = await req.Body.AsStringAsync();

                    try
                    {
                        document = BsonDocument.Parse(json);
                    }
                    catch (Exception err)
                    {
                        logger.LogError(err.Message);
                        res.StatusCode = Status400BadRequest;
                        return;
                    }
                }

                // Manual validation, because Fluent Validation would remove extra properties
                if (!document.Contains("frameInfo") ||
                    document["frameInfo"].BsonType != BsonType.Document ||
                    !document["frameInfo"].AsBsonDocument.Contains("realtimeSinceStartup") ||
                    document["frameInfo"]["realtimeSinceStartup"].BsonType != BsonType.Double)
                {
                    res.StatusCode = Status400BadRequest;
                    return;
                }

                captureRepo.Configure($"sessions.{shortID}");
                await captureRepo.Add(document);

                var filter = Builders <SessionSchema> .Filter.Where(s => s.Id == shortID);

                // This lastCaptureAt is undefined on the session document until the first call of this endpoint
                // Export flags are reset so the session can be re-exported
                var update = Builders <SessionSchema> .Update
                             .Set(s => s.LastCaptureAt, new BsonDateTime(date.UtcNow))
                             .Set(s => s.ExportState, ExportOptions.NotStarted);

                await sessionRepo.Update(filter, update);

                await res.FromString();
            });

            this.Get <GetSession>("/{id}", async(req, res) =>
            {
                string shortID = req.RouteValues.As <string>("id");

                var sessionDoc = await sessionRepo
                                 .FindById(shortID);

                if (sessionDoc == null)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                var startRange = new BsonDateTime(date.UtcNow.AddSeconds(-300)); // 5 minutes
                var closeRange = new BsonDateTime(date.UtcNow.AddSeconds(-5));   // 5 seconds
                bool isStarted = false;

                // Check if key exists
                if (sessionDoc.LastCaptureAt != BsonNull.Value)
                {
                    isStarted = true;
                }

                bool isOngoing;
                if (sessionDoc.IsOpen)
                {
                    isOngoing = (!isStarted &&
                                 startRange.CompareTo(sessionDoc.CreatedAt) < 0) ||
                                (isStarted &&
                                 closeRange.CompareTo(sessionDoc.LastCaptureAt) < 0);
                }
                else
                {
                    isOngoing = false;
                }

                sessionDoc.IsOngoing       = isOngoing;
                sessionDoc.InternalId      = null;
                sessionDoc.User.InternalId = null;

                string json = JsonQuery.FulfilEncoding(req.Query, sessionDoc);
                if (json != null)
                {
                    await res.FromJson(json);
                    return;
                }

                await res.FromBson(sessionDoc);
            });

            this.Delete <DeleteSession>("/{id}", async(req, res) =>
            {
                string shortID = req.RouteValues.As <string>("id");

                var filter     = Builders <SessionSchema> .Filter.Where(s => s.Id == shortID);
                var sessionDoc = await sessionRepo
                                 .FindById(shortID);

                if (sessionDoc == null)
                {
                    res.StatusCode = Status404NotFound;
                    return;
                }

                var update = Builders <SessionSchema> .Update
                             .Set(s => s.IsOpen, false);

                await sessionRepo.Update(filter, update);
                await res.FromString();
            });
        }