Beispiel #1
0
        public static ConfirmPayoutResult ConfirmPayout(string protoIdentity)
        {
            protoIdentity = HttpUtility.UrlDecode(protoIdentity);

            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (
                !authData.Authority.HasAccess(new Access(authData.CurrentOrganization, AccessAspect.Financials,
                                                         AccessType.Write)))
            {
                throw new SecurityException("Insufficient privileges for operation");
            }

            ConfirmPayoutResult result = new ConfirmPayoutResult();

            Payout payout = Payout.CreateFromProtoIdentity(authData.CurrentUser, protoIdentity);

            PWEvents.CreateEvent(EventSource.PirateWeb, EventType.PayoutCreated,
                                 authData.CurrentUser.Identity, 1, 1, 0, payout.Identity,
                                 protoIdentity);

            // Create result and return it

            result.AssignedId     = payout.Identity;
            result.DisplayMessage = String.Format(Resources.Pages.Financial.PayOutMoney_PayoutCreated, payout.Identity,
                                                  payout.Recipient);

            result.DisplayMessage = CommonV5.JavascriptEscape(result.DisplayMessage);

            return(result);
        }
        public static AjaxCallResult Commence(int personId)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (!authData.Authority.HasSystemAccess())
            {
                // Restrict impersonation to system-level access for now: it's a debugging tool

                return(new AjaxCallResult
                {
                    Success = false,
                    DisplayMessage = CommonV5.JavascriptEscape(Resources.Pages.Admin.CommenceImpersonation_Failed)
                });
            }

            // BEGIN IMPERSONATION

            Person impersonatedPerson = Person.FromIdentity(personId);

            SwarmopsLogEntry newEntry = SwarmopsLog.CreateEntry(impersonatedPerson,
                                                                new ImpersonationLogEntry {
                ImpersonatorPersonId = authData.CurrentUser.PersonId, Started = true
            });

            newEntry.CreateAffectedObject(authData.CurrentUser); // link impersonator to log entry for searchability

            // Someone who has system level access can always impersonate => no further access control at this time

            // SECURITY CONSIDERATIONS: If somebody replaces/fires a superior? Trivially undoable at the database level

            DateTime  utcNow = DateTime.UtcNow;
            Authority impersonatingAuthority = Authority.FromLogin(impersonatedPerson, authData.CurrentOrganization);

            impersonatingAuthority.Impersonation = new Impersonation
            {
                ImpersonatedByPersonId = authData.CurrentUser.PersonId,
                ImpersonationStarted   = utcNow
            };

            FormsAuthentication.SetAuthCookie(impersonatingAuthority.ToEncryptedXml(), false);
            HttpContext.Current.Response.AppendCookie(new HttpCookie("DashboardMessage", CommonV5.JavascriptEscape(String.Format(Resources.Pages.Admin.CommenceImpersonation_Success, utcNow))));
            return(new AjaxCallResult {
                Success = true
            });
        }
Beispiel #3
0
        public static AjaxCallResult SignupParticipant(string name, int organizationId, string mail, string password, string phone,
                                                       string street1, string street2, string postalCode, string city, string countryCode, string dateOfBirth,
                                                       int geographyId, bool activist, PersonGender gender, int[] positionIdsVolunteer)
        {
            CommonV5.CulturePreInit(HttpContext.Current.Request);  // Set culture, for date parsing

            if (geographyId == 0)
            {
                geographyId = Geography.RootIdentity; // if geo was undetermined, set it to "Global"
            }

            Organization organization      = Organization.FromIdentity(organizationId);
            DateTime     parsedDateOfBirth = new DateTime(1800, 1, 1); // Default if unspecified

            if (dateOfBirth.Length > 0)
            {
                parsedDateOfBirth = DateTime.Parse(dateOfBirth);
            }

            Person newPerson = Person.Create(name, mail, password, phone, street1 + "\n" + street2.Trim(), postalCode,
                                             city, countryCode, parsedDateOfBirth, gender);
            Participation participation = newPerson.AddParticipation(organization, DateTime.UtcNow.AddYears(1));    // TODO: set duration from organization settings of Participantship

            // TODO: SEND NOTIFICATIONS

            // Log the signup

            SwarmopsLog.CreateEntry(newPerson, new PersonAddedLogEntry(participation, newPerson));

            // Create notification

            OutboundComm.CreateParticipantNotification(newPerson, newPerson, organization,
                                                       NotificationResource.Participant_Signup);

            // Add the bells and whistles

            if (activist)
            {
                newPerson.CreateActivist(false, false);
            }

            if (positionIdsVolunteer.Length > 0)
            {
                Volunteer volunteer = newPerson.CreateVolunteer();
                foreach (int positionId in positionIdsVolunteer)
                {
                    Position position = Position.FromIdentity(positionId);
                    volunteer.AddPosition(position);
                    SwarmopsLog.CreateEntry(newPerson, new VolunteerForPositionLogEntry(newPerson, position));
                }
            }

            newPerson.LastLogonOrganizationId = organizationId;

            // Create a welcome message to the Dashboard

            HttpContext.Current.Response.AppendCookie(new HttpCookie("DashboardMessage", CommonV5.JavascriptEscape(String.Format(Resources.Pages.Public.Signup_DashboardMessage, organization.Name))));

            // Set authentication cookie, which will log the new person in using the credentials just given

            FormsAuthentication.SetAuthCookie(Authority.FromLogin(newPerson).ToEncryptedXml(), true);

            AjaxCallResult result = new AjaxCallResult {
                Success = true
            };

            return(result);
        }
Beispiel #4
0
 protected string JavascriptEscape(string input)
 {
     return(CommonV5.JavascriptEscape(input));
 }
Beispiel #5
0
        private static AjaxCallResult HandleAttestationDeattestation(string identifier, AttestationMode mode)
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            IAttestable attestableItem;
            string      attestedTemplate;
            string      deattestedTemplate;

            char   costType = identifier[0];
            int    itemId   = Int32.Parse(identifier.Substring(1));
            Int64  amountCents;
            string beneficiary;
            string result;

            // Find the item we are attesting or deattesting

            switch (costType)
            {
            case 'A':     // Case advance
                CashAdvance advance = CashAdvance.FromIdentity(itemId);
                if (advance.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (advance.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    advance.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                attestableItem     = advance;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_AdvanceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_AdvanceDeattested;
                beneficiary        = advance.Person.Name;
                amountCents        = advance.AmountCents;

                break;

            case 'E':     // Expense claim
                ExpenseClaim expense = ExpenseClaim.FromIdentity(itemId);
                if (expense.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (expense.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    expense.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                attestableItem     = expense;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ExpenseAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ExpenseDeattested;
                beneficiary        = expense.Claimer.Name;
                amountCents        = expense.AmountCents;

                break;

            case 'I':     // Inbound invoice
                InboundInvoice invoice = InboundInvoice.FromIdentity(itemId);
                if (invoice.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (invoice.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    invoice.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                attestableItem     = invoice;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_InvoiceAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_InvoiceDeattested;
                beneficiary        = invoice.Supplier;
                amountCents        = invoice.AmountCents;

                break;

            case 'S':     // Salary payout
                Salary salary = Salary.FromIdentity(itemId);
                if (salary.PayrollItem.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (salary.PayrollItem.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    salary.PayrollItem.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                attestableItem     = salary;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_SalaryAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_SalaryDeattested;
                beneficiary        = salary.PayrollItem.PersonCanonical;
                amountCents        = salary.GrossSalaryCents + salary.AdditiveTaxCents;

                break;

            case 'P':     // Parley, aka Conference
                Parley parley = Parley.FromIdentity(itemId);
                if (parley.OrganizationId != authData.CurrentOrganization.Identity)
                {
                    throw new InvalidOperationException("Called to attest out-of-org line item");
                }
                if (parley.Budget.OwnerPersonId != authData.CurrentUser.Identity &&
                    parley.Budget.OwnerPersonId != Person.NobodyId)
                {
                    throw new SecurityException("Called without attestation privileges");
                }

                attestableItem     = parley;
                attestedTemplate   = Resources.Pages.Financial.AttestCosts_ParleyAttested;
                deattestedTemplate = Resources.Pages.Financial.AttestCosts_ParleyDeattested;
                beneficiary        = parley.Person.Name;
                amountCents        = parley.BudgetCents;

                break;

            default:
                throw new InvalidOperationException("Unknown Cost Type in HandleAttestationDeattestation: \"" +
                                                    identifier + "\"");
            }

            // Finally, attest or deattest

            if (mode == AttestationMode.Attestation)
            {
                Int64 budgetRemaining = attestableItem.Budget.GetBudgetCentsRemaining();

                result = string.Empty;

                if (amountCents > -budgetRemaining)
                {
                    if (
                        authData.Authority.HasAccess(new Access(authData.CurrentOrganization,
                                                                AccessAspect.Administration)))
                    {
                        // Admin rights, so allow (forced) overdraft

                        // Unless budget was nonzero and allocated, set protest message

                        if (attestableItem.Budget.Owner != null || attestableItem.Budget.GetBudgetCents() != 0)
                        {
                            result = Resources.Pages.Financial.AttestCosts_Overdrafted + " ";
                        }
                    }
                    else
                    {
                        // Do not allow overdraft

                        return(new AjaxCallResult
                        {
                            DisplayMessage = CommonV5.JavascriptEscape(Resources.Pages.Financial.AttestCosts_OutOfBudget),
                            Success = false
                        });
                    }
                }

                attestableItem.Attest(authData.CurrentUser);
                result += string.Format(attestedTemplate, itemId, beneficiary,
                                        authData.CurrentOrganization.Currency.Code,
                                        amountCents / 100.0);
            }
            else if (mode == AttestationMode.Deattestation)
            {
                attestableItem.Deattest(authData.CurrentUser);
                result = string.Format(deattestedTemplate, itemId, beneficiary,
                                       authData.CurrentOrganization.Currency.Code,
                                       amountCents / 100.0);
            }
            else
            {
                throw new InvalidOperationException("Unknown Attestation Mode: " + mode);
            }

            FinancialAccount.ClearAttestationAdjustmentsCache(authData.CurrentOrganization);

            return(new AjaxCallResult {
                DisplayMessage = CommonV5.JavascriptEscape(result), Success = true
            });
        }
Beispiel #6
0
 public string JavascriptEscape(string input)
 {
     return(CommonV5.JavascriptEscape(input));
 }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (CurrentUser == null)
            {
                throw new UnauthorizedAccessException("No");  // may cause problems on login screen?
            }

            PageAccessRequired = new Access(AccessAspect.Null);

            string       returnUrlString       = Request.QueryString["ReturnUrl"];
            string       organizationIdString  = Request.QueryString["OrganizationId"];
            int          organizationId        = Int32.Parse(organizationIdString);
            Organization suggestedOrganization = null;

            try
            {
                suggestedOrganization = Organization.FromIdentity(organizationId);
            }
            catch (ArgumentException)
            {
                suggestedOrganization = null;
            }

            if (suggestedOrganization.Identity == Organization.SandboxIdentity &&
                !CurrentUser.ParticipatesInOrganization(suggestedOrganization))
            {
                // Add a forever participation in Sandbox

                Participation.Create(CurrentUser, Organization.Sandbox, Constants.DateTimeHigh);
            }
            else if (suggestedOrganization == null || !CurrentUser.ParticipatesInOrganization(suggestedOrganization))
            {
                // Some work here on PPSE pilot - we want everybody to be able to switch to Sandbox, which is #1
                // except for in PPSE installation, where it is... #3 or something

                // TODO: Allow logon to organization if there is a Position active

                throw new UnauthorizedAccessException();
            }

            // when we get here, we are authorized to log on to the suggested organization.

            // The reason we're modifying the existing Authority object instead of creating a new one
            // is to minimize the risk for impersonation exploits: The only way to assign a Person identity
            // to an Authority object is on login.

            Authority newAuthority = CurrentAuthority;

            newAuthority.SetOrganization(suggestedOrganization);  // will/can also modify Position
            CurrentUser.LastLogonOrganizationId = suggestedOrganization.Identity;

            if (suggestedOrganization.Identity == Organization.SandboxIdentity)
            {
                // Set a dashboard message that the user is now working in Sandbox

                Response.SetCookie(new HttpCookie("DashboardMessage",
                                                  CommonV5.JavascriptEscape(Resources.Global.Global_EnteringSandbox)));
            }

            if (!string.IsNullOrEmpty(returnUrlString))
            {
                FormsAuthentication.SetAuthCookie(newAuthority.ToEncryptedXml(), true);
                Response.Redirect(returnUrlString);
            }
            else
            {
                FormsAuthentication.RedirectFromLoginPage(newAuthority.ToEncryptedXml(), true);
            }
        }
Beispiel #8
0
        public static AjaxCallResult TerminateImpersonation()
        {
            AuthenticationData authData = GetAuthenticationDataAndCulture();

            if (!authData.Authority.ImpersonationActive)
            {
                return(new AjaxCallResult {
                    Success = false
                });                                          // no impersonation active. Race condition?
            }

            int    realUserPersonId = authData.Authority.Impersonation.ImpersonatedByPersonId;
            Person impersonator     = Person.FromIdentity(realUserPersonId);

            // Terminate impersonation and set new authority cookie from the impersonator data.
            // VERY SECURITY SENSITIVE: The identity as impersonator will be the new user.

            // TODO: LOG LOG LOG LOG

            SwarmopsLogEntry logEntry = SwarmopsLog.CreateEntry(authData.CurrentUser,
                                                                new ImpersonationLogEntry
            {
                ImpersonatorPersonId = impersonator.Identity,
                Started = false
            });

            logEntry.CreateAffectedObject(impersonator); // link impersonator to log entry for searchability

            DateTime utcNow = DateTime.UtcNow;

            Authority authority =
                Authority.FromLogin(impersonator, authData.CurrentOrganization);

            FormsAuthentication.SetAuthCookie(authority.ToEncryptedXml(), false);
            HttpContext.Current.Response.AppendCookie(new HttpCookie("DashboardMessage", CommonV5.JavascriptEscape(String.Format(Resources.Pages.Admin.CommenceImpersonation_Ended, utcNow))));

            // returning Success will force a reload, resetting dashboard to original user

            return(new AjaxCallResult {
                Success = true
            });
        }