public bool HasSystemAccess(AccessType accessType = AccessType.Write) { // TODO: CHECK POSITION ASSIGNMENT // for now, check if position assignment exists // This is not very efficient, but there shouldn't be many system-level positions or // assignments, so it should scale reasonably even in an 1M organization PositionAssignments assignments = Positions.ForSystem().Assignments; foreach (PositionAssignment assignment in assignments) { if (assignment.Active && assignment.PersonId == this._data.PersonId) { if ((assignment.Position.PositionType == PositionType.System_SysadminMain || assignment.Position.PositionType == PositionType.System_SysadminReadWrite)) { return(true); } if (assignment.Position.PositionType == PositionType.System_SysadminAssistantReadOnly && accessType == AccessType.Read) { return(true); // Read-only access } } } return(false); }
private void CheckSysadminsPopulated() { Positions systemPositions = Positions.ForSystem(); if (systemPositions.Count == 0) { // not initalized. Initialize. Positions.CreateSysadminPositions(); systemPositions = Positions.ForSystem(); } PositionAssignments assignments = systemPositions.Assignments; if (assignments.Count == 0) { // The positions exist, but nothing was assigned to them. // Assign sysadmins as the org admins from org #1. (Grandfathering procedure.) // This code can safely be removed once all the pilots can be certain to have run it, that is, // by the release of sprint Red-5. Organization template = Organization.FromIdentity(1); string readWriteIdsString = template.Parameters.TemporaryAccessListWrite; string[] readWriteIdsArray = readWriteIdsString.Trim().Replace(" ", " ").Split(' '); string readOnlyIdsString = template.Parameters.TemporaryAccessListRead; string[] readOnlyIdsArray = readOnlyIdsString.Trim().Replace(" ", " ").Split(' '); Position rootSysadmin = Position.RootSysadmin; rootSysadmin.Assign(Person.FromIdentity(Int32.Parse(readWriteIdsArray[0])), null /*assignedby*/, null /*assignedby*/, "Initial sysadmin", null /*does not expire*/); Positions rootChildren = rootSysadmin.Children; Position sysadminRW = rootChildren.Where(position => position.PositionType == PositionType.System_SysadminReadWrite).ToList() [0]; // should exist Position sysadminAssistantRO = rootChildren.Where( position => position.PositionType == PositionType.System_SysadminAssistantReadOnly).ToList()[0]; for (int readWriteIndex = 1; readWriteIndex < readWriteIdsArray.Length; readWriteIndex++) { sysadminRW.Assign(Person.FromIdentity(int.Parse(readWriteIdsArray[readWriteIndex])), null /*assignedBy*/, null /*assignedBy*/, "Initial sysadmin", null /*does not expire*/); } foreach (string readOnlyPersonIdString in readOnlyIdsArray) { if (readOnlyPersonIdString != "1") { sysadminAssistantRO.Assign(Person.FromIdentity(int.Parse(readOnlyPersonIdString)), null /*assignedBy*/, null /*assignedBy*/, "Initial sysadmin assistant", null /*does not expire*/); } } } }
internal override void Plus(XDocument xdoc) { foreach (var element in xdoc.Root.Elements()) { var val = element.Value; int valI; int.TryParse(val, out valI); switch (element.Name.LocalName) { case "id": break; case "race_id": if (valI != -1 && World.Races.ContainsKey(valI)) { Race = World.Races[valI]; } break; case "type": if (!Types.Contains(val)) { Types.Add(val); } _entityType = (short)Types.IndexOf(val); break; case "site_link": var newSl = new EntitySiteLink(element, this); if (SiteLinks == null) { SiteLinks = new Dictionary <int, List <EntitySiteLink> >(); } if (!SiteLinks.ContainsKey(newSl.LinkType)) { SiteLinks.Add(newSl.LinkType, new List <EntitySiteLink>()); } SiteLinks[newSl.LinkType].Add(newSl); break; case "entity_link": var newEl = new EntityEntityLink(element, this); if (EntityLinks == null) { EntityLinks = new Dictionary <int, List <EntityEntityLink> >(); } if (!EntityLinks.ContainsKey(newEl.LinkType)) { EntityLinks.Add(newEl.LinkType, new List <EntityEntityLink>()); } EntityLinks[newEl.LinkType].Add(newEl); break; case "children": ChildrenIDs = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList(); break; case "worship_id": WorshipHfid = valI; break; case "coords": if (Coords == null) { Coords = new List <Point>(); } foreach (var coordSplit in val.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries).Select(coord => coord.Split(',')).Where(coordSplit => coordSplit.Length == 2)) { Coords.Add(new Point(Convert.ToInt32(coordSplit[0]), Convert.ToInt32(coordSplit[1]))); } break; case "claims": Claims = val.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Select(coord => coord.Split(',')) .Where(coordSplit => coordSplit.Length == 2) .Select(split => new Point(Convert.ToInt32(split[0]), Convert.ToInt32(split[1]))) .ToList(); break; case "entity_position": var newPosition = new EntityPosition(element, this); if (Positions == null) { Positions = new List <EntityPosition>(); } Positions.Add(newPosition); break; case "entity_position_assignment": var newPositionAssignment = new EntityPositionAssignment(element, this); if (PositionAssignments == null) { PositionAssignments = new List <EntityPositionAssignment>(); } PositionAssignments.Add(newPositionAssignment); break; case "histfig_id": if (MemberHfids == null) { MemberHfids = new List <int>(); } MemberHfids.Add(valI); break; case "histfig_ids": MemberHfids = val.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => Convert.ToInt32(x)).ToList(); break; case "occasion": var newOccasion = new EntityOccasion(element, this); if (Occasions == null) { Occasions = new List <EntityOccasion>(); } Occasions.Add(newOccasion); break; default: DFXMLParser.UnexpectedXmlElement(xdoc.Root.Name.LocalName + "\t", element, xdoc.Root.ToString()); break; } } }
private string RecursePositionTree(List <TreeNode <Position> > positionNodes) { List <string> elements = new List <string>(); string reportsTo = string.Empty; if (positionNodes.Count > 0 && positionNodes[0].Data.ParentIdentity != 0) { } foreach (TreeNode <Position> positionNode in positionNodes) { Position position = positionNode.Data; string localizedPositionName = position.Localized(positionNode.Data.MaxCount != 1); PositionAssignments assignments = new PositionAssignments(); string nodeState = "open"; if (position.GeographyId != _geographyId) { localizedPositionName += " " + position.Geography.Name; nodeState = "closed"; } string expires = string.Empty; string action = string.Empty; string assignedName = string.Empty; if (_displayAssignments) { assignments = position.Assignments; assignedName = Resources.Controls.Swarm.Positions_Vacant; } if (_assignable) { assignedName = string.Format( "<a positionId='{3}' geographyId='{5}' positionName='{4}' class='{1} LocalAssignPerson'>{2}</a> {0}", Resources.Controls.Swarm.Positions_Vacant, _customCookieClass, Resources.Controls.Swarm.Positions_AssignFirstPerson, position.Identity, JavascriptEscape(position.Localized()), position.GeographyId); } if (localizedPositionName == null) { localizedPositionName = @"NULL (" + position.PositionType.ToString() + ")"; string test = position.Localized(); } if (assignments.Count > 0) { assignedName = assignments[0].Person.Canonical; if (assignments[0].ExpiresDateTimeUtc.IsDefined()) { expires = assignments[0].ExpiresDateTimeUtc.ToString("yyyy-MMM-dd"); } if (_assignable) { action = String.Format( "<img class='LocalIconTerminate {1}' height='18' width='24' {2} assignmentId='{0}' />", assignments[0].Identity, _customCookieClass, assignments[0].PersonId == CurrentUser.Identity ? "self='true'" : string.Empty); } } string element = string.Empty; if (position.PositionTitle != PositionTitle.UxElement) // regular title type { element = string.Format( "\"id\":\"{0}-1-{8}\",\"positionTitle\":\"{1}\",\"assignedName\":\"{2}\",\"expires\":\"{3}\",\"minMax\":\"{4} / {5}\",\"iconType\":\"{6}\",\"actions\":\"{7}\"", position.Identity, JsonSanitize(localizedPositionName), JsonSanitize(assignedName), JsonSanitize(expires), position.MinCount, position.MaxCount == 0 ? @"∞" : position.MaxCount.ToString(CultureInfo.InvariantCulture), position.MaxCount == 1 ? "Person" : "Group", action, position.GeographyId); } else // UX element { nodeState = "closed"; element = string.Format( "\"id\":\"{0}-1-{8}\",\"positionTitle\":\"{1}\",\"assignedName\":\"\",\"expires\":\"\",\"minMax\":\"\",\"iconType\":\"{6}\",\"actions\":\"\"", position.Identity, JsonSanitize(localizedPositionName), JsonSanitize(assignedName), JsonSanitize(expires), position.MinCount, position.MaxCount == 0 ? @"∞" : position.MaxCount.ToString(CultureInfo.InvariantCulture), position.MaxCount == 1 ? "Person" : "Group", action, position.GeographyId); } // TODO: Add all assignments after the first one right here int assignmentCount = 1; while (assignmentCount < assignments.Count) { // add more lines to match the number of assignments for this position elements.Add("{" + element + "}"); expires = string.Empty; if (_assignable) { action = String.Format( "<img class='LocalIconTerminate {1}' height='18' width='24' {2} assignmentId='{0}' />", assignments[assignmentCount].Identity, _customCookieClass, assignments[0].PersonId == CurrentUser.Identity ? "self='true'" : string.Empty); } DateTime expiresUtc = assignments[assignmentCount].ExpiresDateTimeUtc; if (expiresUtc.IsDefined()) { expires = expiresUtc.ToString("yyyy-MMM-dd"); } element = String.Format( "\"id\":\"{0}-{1}\",\"iconType\":\"Hidden\",\"positionTitle\":\" \",\"assignedName\":\"{2}\",\"expires\":\"{3}\",\"actions\":\"{4}\"", position.Identity, assignmentCount + 1, assignments[assignmentCount].Person.Canonical, expires, action); assignmentCount++; } if (_assignable && (assignmentCount < position.MaxCount || (position.MaxCount == 0 && position.Assignments.Count > 0))) { // finally, if the assigned count is less than max count, add a "assign another person" link if _assignable is true int count = position.Assignments.Count; if (count > 6) { count = 6; } string[] overEngineeredAssignmentPrompts = { Resources.Controls.Swarm.Positions_AssignFirstPerson, Resources.Controls.Swarm.Positions_AssignSecondPerson, Resources.Controls.Swarm.Positions_AssignThirdPerson, Resources.Controls.Swarm.Positions_AssignFourthPerson, Resources.Controls.Swarm.Positions_AssignFifthPerson, Resources.Controls.Swarm.Positions_AssignSixthPerson, Resources.Controls.Swarm.Positions_AssignAnotherPerson }; elements.Add("{" + element + "}"); string addPerson = string.Format( "<a positionId='{1}' geographyId='{4}' positionName='{2}' class='{3} LocalAssignPerson'>{0}</a>", overEngineeredAssignmentPrompts[count], position.Identity, JavascriptEscape(position.Localized()), _customCookieClass, position.GeographyId); element = String.Format( "\"id\":\"{0}-0\",\"iconType\":\"Hidden\",\"positionTitle\":\" \",\"assignedName\":\"{1}\"", position.Identity, addPerson); } if (positionNode.Children.Count > 0) // This should only trigger when position.MaxCount is also 1, or a very weird UI will result { element += ",\"state\":\"" + nodeState + "\",\"children\":" + RecursePositionTree(positionNode.Children); } elements.Add("{" + element + "}"); } return("[" + String.Join(",", elements.ToArray()) + "]"); }
public static AjaxCallResult AssignPosition(int personId, int positionId, int durationMonths, int geographyId) { AuthenticationData authData = GetAuthenticationDataAndCulture(); Position position = Position.FromIdentity(positionId); Person person = Person.FromIdentity(personId); Geography geography = (geographyId == 0 ? null : Geography.FromIdentity(geographyId)); if (position.PositionLevel == PositionLevel.Geography || position.PositionLevel == PositionLevel.GeographyDefault) { position.AssignGeography(geography); } if ((position.OrganizationId > 0 && authData.CurrentOrganization.Identity != position.OrganizationId) || person.Identity < 0) { throw new UnauthorizedAccessException(); } if (position.PositionLevel == PositionLevel.SystemWide && !authData.Authority.HasAccess(new Access(AccessAspect.Administration))) { // Authority check for systemwide throw new UnauthorizedAccessException(); } if ((position.GeographyId == Geography.RootIdentity || position.GeographyId == 0) && !authData.Authority.HasAccess(new Access(authData.CurrentOrganization, AccessAspect.Administration))) { // Authority check for org-global throw new UnauthorizedAccessException(); } if ( !authData.Authority.HasAccess(new Access(authData.CurrentOrganization, geography, AccessAspect.Administration))) { // Authority check for org/geo combo throw new UnauthorizedAccessException(); } if (position.MaxCount > 0 && position.Assignments.Count >= position.MaxCount) { return(new AjaxCallResult { Success = false, DisplayMessage = Resources.Controls.Swarm.Positions_NoMorePeopleOnPosition }); } // Deliberate: no requirement for membership (or equivalent) in order to be assigned to position. // Find the current user position used to assign. PositionAssignments currentUserAssignments = authData.CurrentUser.PositionAssignments; // Get the one this user is currently using to assign - it's either a system level position, // one with a parent organization (TODO), or one with this organization Position activePosition = null; foreach (PositionAssignment currentUserAssignment in currentUserAssignments) { if (currentUserAssignment.OrganizationId == 0 && currentUserAssignment.Active) { activePosition = currentUserAssignment.Position; break; // a system-level active position has priority over org-level } if (currentUserAssignment.OrganizationId == authData.CurrentOrganization.Identity && currentUserAssignment.Active) { activePosition = currentUserAssignment.Position; } } if (activePosition == null) { return(new AjaxCallResult { Success = false, DisplayMessage = "Error: No authority to assign a position" }); } DateTime?expiresUtc = null; if (durationMonths > 0) { expiresUtc = DateTime.UtcNow.AddMonths(durationMonths); } try { PositionAssignment.Create(position, geography, person, authData.CurrentUser, activePosition, expiresUtc, string.Empty); } catch (DatabaseConcurrencyException) { return(new AjaxCallResult { Success = false, DisplayMessage = Resources.Global.Error_DatabaseConcurrency }); } return(new AjaxCallResult { Success = true }); }