/// <summary> /// Initialize a student in the system. /// Create the student in the DB and add him some aditional properties. /// </summary> /// <param name="context"></param> /// <param name="email"></param> /// <param name="fullname"></param> /// <param name="password"></param> /// <param name="career"></param> /// <param name="group"></param> /// <param name="year"></param> /// <returns> /// A new instance of the student. The changes has to be saved /// in the returned object. /// </returns> public Student CreateStudentInSystem(string email, string fullname, string password, string career, string group, int year) { var student = new Student(fullname, email, password, career, group, year); student.Password = student.PasswordHasher(password); //create the necessary properties for the students // // create the DAV:group-membership var gMembership = PropertyCreation.CreateGroupMembership(SystemProperties._groupPrincipalUrl + group + "/"); //create the displayname var displayName = PropertyCreation.CreateProperty("displayname", "D", fullname); //create the principal the represents the user var principal = new Principal(email, SystemProperties.PrincipalType.Student, gMembership, displayName); student.Principal = principal; principal.User = student; //take the collection with user group name var collection = _context.CalendarCollections.FirstOrDefault( col => col.Url == SystemProperties._groupCollectionUrl + group); //if the collection doent exit then something is wrong with the group //and either has to be created or the user group is not valid if (collection == null) { throw new InvalidDataException("The user group doesnt exit in the system." + "Check if the user group is valid or create the group collection in the system."); } //create the calendar-home-set var calHomeSet = PropertyCreation.CreateCalendarHomeSet(SystemProperties.PrincipalType.Group, group, collection.Name); //add the property to the principal principal.Properties.Add(calHomeSet); _context.Students.Add(student); _context.Principals.Add(principal); _context.SaveChanges(); return(student); }
public void TakingCurrentUserPrivilegeSet() { var principal = new Principal { PrincipalURL = "principals/users/principal1" }; var aclProperty = PropertyCreation.CreateAclPropertyForUserCollections(principal.PrincipalURL); var permissions = principal.GetCurrentUserPermissions(aclProperty); IXMLTreeStructure child = null; Assert.Equal(permissions.NodeName, "current-user-privilege-set"); Assert.True(permissions.GetChildAtAnyLevel("read", out child)); Assert.True(permissions.GetChildAtAnyLevel("write", out child)); }
public Worker CreateWorkerInSystem(string email, string password, string fullName, string faculty, string department) { var worker = new Worker(fullName, email, password, department, faculty); worker.Password = worker.PasswordHasher(password); //create useful properties for the principal var calHomeSet = PropertyCreation.CreateCalendarHomeSet(SystemProperties.PrincipalType.User, email, SystemProperties._defualtInitialCollectionName); var displayName = PropertyCreation.CreateProperty("displayname", "D", fullName); //create the principal the represents the user var principal = new Principal(email, SystemProperties.PrincipalType.User, displayName, calHomeSet); worker.Principal = principal; //create the collection for the user. var col = new CalendarCollection( $"{SystemProperties._userCollectionUrl}{email}/{SystemProperties._defualtInitialCollectionName}/", SystemProperties._defualtInitialCollectionName) { Principal = principal }; //add the calaendar to the collection of the principal principal.CalendarCollections.Add(col); //create the folder that will contain the //calendars of the user new FileSystemManagement().AddCalendarCollectionFolder(col.Url); //add the user and its principal to the context _context.Workers.Add(worker); _context.Principals.Add(principal); _context.CalendarCollections.Add(col); _context.SaveChanges(); return(worker); }
/// <summary> /// Add a user to the system. /// </summary> /// <param name="context">The system Db context.</param> /// <param name="email">The user email.</param> /// <param name="fullName">The user full name. This gonna be the displayname for the system.</param> /// <param name="password">THe user not encrypted password</param> /// <returns> /// The instance of the new User. Have to change the changes with the /// returned object. /// </returns> public Principal CreateUserInSystem(string email, string fullName, string password) { //create the core passHasher var passHasher = new PasswordHasher <User>(); var user = new User { Email = email, Password = password, DisplayName = fullName }; var defaultCalName = email; //create useful properties for the principal var calHomeSet = PropertyCreation.CreateCalendarHomeSet(SystemProperties.PrincipalType.User, email, defaultCalName); var displayName = PropertyCreation.CreateProperty("displayname", "D", fullName); //create the principal the represents the user var principal = new Principal(email, SystemProperties.PrincipalType.User, displayName, calHomeSet); user.Principal = principal; #region create the collection for the principal //create the collection for the user. var col = new CalendarCollection( $"{SystemProperties._userCollectionUrl}{email}/{defaultCalName}/", defaultCalName) { Principal = principal }; //add the ACL properties to the collection var ownerProp = PropertyCreation.CreateProperty("owner", "D", $"<D:href>{principal.PrincipalURL}</D:href>", false, false); col.Properties.Add(ownerProp); col.Properties.Add(PropertyCreation.CreateAclPropertyForUserCollections(principal.PrincipalURL)); //add the calaendar to the collection of the principal principal.CalendarCollections.Add(col); #endregion //create the folder that will contain the //calendars of the user new FileSystemManagement().AddCalendarCollectionFolder(col.Url); //hass the user password // the instance of the user has to be pass but is not used // so it need to be updated var hashedPassword = passHasher.HashPassword(user, password); user.Password = hashedPassword; //add the user and its principal to the context _context.Users.Add(user); _context.Principals.Add(principal); _context.CalendarCollections.Add(col); _context.SaveChanges(); return(principal); }
private void InitializeStandardCollectionProperties(string name) { Properties.Add(new Property("calendar-timezone", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<C:calendar-timezone {_namespaces["C"]}>LaHabana/Cuba</C:calendar-timezone>" }); Properties.Add(new Property("max-resource-size", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<C:max-resource-size {_namespaces["C"]}>102400</C:max-resource-size>" }); Properties.Add(new Property("min-date-time", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<C:min-date-time {_namespaces["C"]}>{SystemProperties.MinDateTime()}</C:min-date-time>" }); Properties.Add(new Property("max-date-time", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<C:max-date-time {_namespaces["C"]}>{SystemProperties.MaxDateTime()}</C:max-date-time>" }); Properties.Add(new Property("max-instances", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<C:max-instances {_namespaces["C"]}>10</C:max-instances>" }); Properties.Add(new Property("getcontentlength", _namespacesSimple["D"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<D:getcontentlength {_namespaces["D"]}>0</D:getcontentlength>" }); Properties.Add(new Property("supported-calendar-component-set", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = true, Value = $@"<C:supported-calendar-component-set {_namespaces["C"] }><C:comp name=""VEVENT""/><C:comp name=""VTODO""/></C:supported-calendar-component-set>" }); Properties.Add(new Property("supported-calendar-data", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $@"<C:supported-calendar-data {_namespaces["C"] }><C:comp name=""VEVENT""/><C:comp name=""VTODO""/></C:supported-calendar-data>" }); Properties.Add(new Property("calendar-description", _namespacesSimple["C"]) { IsVisible = true, IsDestroyable = false, IsMutable = true, Value = $"<C:calendar-description {_namespaces["C"]}>No Description Available</C:calendar-description>" }); Properties.Add(new Property("resourcetype", _namespacesSimple["D"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $"<D:resourcetype {_namespaces["D"]}><D:collection/><C:calendar xmlns:C=\"urn:ietf:params:xml:ns:caldav\"/></D:resourcetype>" }); Properties.Add(new Property("displayname", _namespacesSimple["D"]) { IsVisible = true, IsDestroyable = false, IsMutable = true, Value = string.IsNullOrEmpty(name) ? null : $"<D:displayname {_namespaces["D"]}>{name}</D:displayname>" }); Properties.Add(new Property("creationdate", _namespacesSimple["D"]) { IsVisible = true, IsDestroyable = false, IsMutable = true, Value = $"<D:creationdate {_namespaces["D"]}>{DateTime.Now}</D:creationdate>" }); Properties.Add(new Property("getctag", _namespacesSimple["S"]) { IsVisible = true, IsDestroyable = false, IsMutable = false, Value = $@"<S:getctag {_namespaces["S"]} >{Guid.NewGuid()}</S:getctag>" }); Properties.Add(PropertyCreation.CreateSupportedPrivilegeSetForResources()); }
/// <summary> /// Having the principal and the requested properties /// then proccess the requestedProperties and build the /// response. /// </summary> /// <param name="response">The HttpResponse from the controller.</param> /// <param name="requestedUrl">The principal url if anyurl </param> /// <param name="reqProperties">Contains the requested properties for the principal. key=name, Value = ns</param> /// <param name="principal">The instance of the pricipal that is requested</param> /// <returns>The final response to return. Has the body with the response and the</returns> public async Task BuildResponse(HttpResponse response, string requestedUrl, List <KeyValuePair <string, string> > reqProperties, Principal principal) { //if the principal is not authenticated then set in the response statusCode if (principal == null) { response.StatusCode = StatusCodes.Status401Unauthorized; } var multistatusNode = new XmlTreeStructure("multistatus", "DAV:"); multistatusNode.Namespaces.Add("D", "DAV:"); multistatusNode.Namespaces.Add("C", "urn:ietf:params:xml:ns:caldav"); IEnumerable <IXMLTreeStructure> properties = null; //create the response node. var responseNode = new XmlTreeStructure("response", "DAV:"); //create the href node var hrefNode = new XmlTreeStructure("href", "DAV:"); //var url = requestedUrl.Replace(SystemProperties._baseUrl , ""); hrefNode.AddValue(requestedUrl); responseNode.AddChild(hrefNode); //in this section is where the "propstat" structure its build. var propstatNode = new XmlTreeStructure("propstat", "DAV:"); var propNode = new XmlTreeStructure("prop", "DAV:"); //check this because the principal could not be authenticated if (principal != null) { //add the requested properties to the propNode //if the properties exist in the principal properties = principal.Properties .Where(p => reqProperties.Contains(new KeyValuePair <string, string>(p.Name, p.Namespace))) .Select(x => XmlTreeStructure.Parse(x.Value)); } //check the properties that are generated per request //and are not contained in the principal's properties foreach (var reqProperty in reqProperties) { //here the additional properties for the principal that //are created per request switch (reqProperty.Key) { case "current-user-principal": propNode.AddChild(PropertyCreation.CreateCurrentUserPrincipal(principal)); break; case "principal-URL": propNode.AddChild(new XmlTreeStructure("principal-URL", "DAV:") { Value = principal.PrincipalURL }); break; } } if (properties != null) { //add the properties to the propNode foreach (var property in properties) { propNode.AddChild(property); } } var statusNode = new XmlTreeStructure("status", "DAV:") { Value = "HTTP/1.1 200 OK" }; //add the propNOde and the status node to the propStatNode propstatNode.AddChild(propNode).AddChild(statusNode); responseNode.AddChild(propstatNode); multistatusNode.AddChild(responseNode); //here the multistatus xml for the body is built //have to write it to the response body. var responseText = multistatusNode.ToString(); var responseBytes = Encoding.UTF8.GetBytes(responseText); response.ContentLength = responseBytes.Length; await response.Body.WriteAsync(responseBytes, 0, responseBytes.Length); }
/// <summary> /// Method in charge of fill a CalendarResource and Return it. /// </summary> /// <param name="propertiesAndHeaders"></param> /// <param name="iCal"></param> /// <param name="response"></param> /// <returns></returns> private async Task <CalendarResource> FillResource(Dictionary <string, string> propertiesAndHeaders, ICalendarComponentsContainer iCal, HttpResponse response) { #region Extracting Properties string calendarResourceId; propertiesAndHeaders.TryGetValue("calendarResourceId", out calendarResourceId); string url; propertiesAndHeaders.TryGetValue("url", out url); string principalId; propertiesAndHeaders.TryGetValue("principalId", out principalId); //var headers = response.GetTypedHeaders(); #endregion // calculate etag that will notice a change in the resource var etag = $"\"{Guid.NewGuid()}\""; response.Headers["etag"] = etag; var resource = new CalendarResource(url, calendarResourceId); //add the owner property var principal = _principalRepository.GetByIdentifier(principalId); var principalUrl = principal == null ? "" : principal.PrincipalURL; resource.Properties.Add(PropertyCreation.CreateOwner(principalUrl)); resource.Properties.Add(PropertyCreation.CreateAclPropertyForUserCollections(principalUrl)); resource.Properties.Add(PropertyCreation.CreateSupportedPrivilegeSetForResources()); // await _resourceRespository.Add(resource); //adding the calculated etag in the getetag property of the resource var errorStack = new Stack <string>(); await _resourceRespository.CreatePropertyForResource(resource, "getetag", "DAV:", $"<D:getetag {_namespaces["D"]}>{etag}</D:getetag>", errorStack, true); //updating the ctag of the collection noticing this way that the collection has changed. var stack = new Stack <string>(); await _collectionRespository.CreateOrModifyProperty( url?.Remove(url.LastIndexOf("/", StringComparison.Ordinal) + 1), "getctag", _namespacesSimple["S"], $@"<S:getctag {_namespaces["S"]} >{Guid.NewGuid()}</S:getctag>", stack, true); //getting the uid var calendarComponents = iCal.CalendarComponents.FirstOrDefault(comp => comp.Key != "VTIMEZONE").Value; var calendarComponent = calendarComponents.FirstOrDefault(); if (calendarComponent != null) { resource.Uid = calendarComponent.Properties["UID"].StringValue; } return(resource); }