예제 #1
0
 public void SetForeignObject(IHasIdentity foreignObject)
 {
     SwarmDb.GetDatabaseForWriting().SetDocumentForeignObject(this.Identity, GetDocumentTypeForObject(foreignObject), foreignObject.Identity);
 }
예제 #2
0
 public static OutboundInvoice FromIdentity(int outboundInvoiceId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForReading().GetOutboundInvoice(outboundInvoiceId)));
 }
예제 #3
0
        public void AddItem(string description, Int64 amountCents)
        {
            // NOTE: MUST NOT ADD FINANCIAL TRANSACTION LINES HERE; SURCHARGES ARE ADDED AS LINE ITEMS ON PAYMENT

            SwarmDb.GetDatabaseForWriting().CreateOutboundInvoiceItem(Identity, description, amountCents);
        }
예제 #4
0
 public Dictionary <int, int> GetCandidatePersonMap()
 {
     return(SwarmDb.GetDatabaseForReading().GetCandidateIdPersonIdMap(this.Identity));
 }
예제 #5
0
 public void AddCandidate(Person person)
 {
     SwarmDb.GetDatabaseForWriting().CreateBallotCandidate(Identity, person.Identity);
 }
예제 #6
0
        public static void PrimeCountry(string countryCode)
        {
            Country country = Country.FromCode(countryCode);

            if (country.GeographyId != Geography.RootIdentity)
            {
                // already initialized
                return;
            }

            GeographyDataLoader geoDataLoader = new GeographyDataLoader();

            // This next part has been hardened against transient network failures, up to 10 retries

            int  retries        = 0;
            bool networkSuccess = false;

            MasterGeography geography = null;

            MasterCity[]       cities      = null;
            MasterPostalCode[] postalCodes = null;

            while (!networkSuccess)
            {
                try
                {
                    geography      = geoDataLoader.GetGeographyForCountry(countryCode);
                    cities         = geoDataLoader.GetCitiesForCountry(countryCode);
                    postalCodes    = geoDataLoader.GetPostalCodesForCountry(countryCode);
                    networkSuccess = true;
                }
                catch (Exception)
                {
                    if (retries >= 10)
                    {
                        throw;
                    }

                    retries++;
                    Thread.Sleep(5000); // wait five seconds for network conditions to clear
                }
            }

            // ID Translation lists

            Dictionary <int, int>  geographyIdTranslation = new Dictionary <int, int>();
            Dictionary <int, int>  cityIdTranslation      = new Dictionary <int, int>();
            Dictionary <int, bool> cityIdsUsedLookup      = new Dictionary <int, bool>();

            // Create the country's root geography

            int countryRootGeographyId = SwarmDb.GetDatabaseForWriting().CreateGeography(geography.Name,
                                                                                         Geography.RootIdentity);

            geographyIdTranslation[geography.GeographyId] = countryRootGeographyId;
            SwarmDb.GetDatabaseForWriting().SetCountryGeographyId(country.Identity,
                                                                  countryRootGeographyId);

            int count = 0;
            int total = InitDatabaseThreadCountGeographyChildren(geography.Children);

            InitDatabaseThreadCreateGeographyChildren(geography.Children, countryRootGeographyId,
                                                      ref geographyIdTranslation, ref count, total);

            // Find which cities are actually used

            foreach (MasterPostalCode postalCode in postalCodes)
            {
                cityIdsUsedLookup[postalCode.CityId] = true;
            }

            GuidCache.Set("DbInitProgress", "(finalizing)");

            // Insert cities

            int newCountryId = country.Identity;

            int cityIdHighwater =
                SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommandScalar("SELECT Max(CityId) FROM Cities;");

            StringBuilder sqlCityBuild =
                new StringBuilder("INSERT INTO Cities (CityName, GeographyId, CountryId, Comment) VALUES ", 65536);
            bool insertComma = false;

            foreach (MasterCity city in cities)
            {
                if (!geographyIdTranslation.ContainsKey(city.GeographyId))
                {
                    cityIdsUsedLookup[city.CityId] = false; // force non-use of invalid city
                }

                if ((cityIdsUsedLookup.ContainsKey(city.CityId) && cityIdsUsedLookup[city.CityId]) || country.PostalCodeLength == 0)
                {
                    int newGeographyId = geographyIdTranslation[city.GeographyId];

                    if (insertComma)
                    {
                        sqlCityBuild.Append(",");
                    }

                    sqlCityBuild.Append("('" + city.Name.Replace("'", "\\'") + "'," + newGeographyId + "," +
                                        newCountryId + ",'')");
                    insertComma = true;

                    cityIdTranslation[city.CityId] = ++cityIdHighwater; // Note that we assume the assigned ID here.
                }
            }

            sqlCityBuild.Append(";");

            SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommand(sqlCityBuild.ToString());
            // Inserts all cities in one bulk op, to save roundtrips

            // Insert postal codes, if any

            if (postalCodes.Length > 0)
            {
                StringBuilder sqlBuild =
                    new StringBuilder("INSERT INTO PostalCodes (PostalCode, CityId, CountryId) VALUES ", 65536);
                insertComma = false;

                foreach (MasterPostalCode postalCode in postalCodes)
                {
                    if (cityIdsUsedLookup[postalCode.CityId] == false)
                    {
                        // Remnants of invalid pointers

                        continue;
                    }

                    int newCityId = cityIdTranslation[postalCode.CityId];

                    if (insertComma)
                    {
                        sqlBuild.Append(",");
                    }

                    sqlBuild.Append("('" + postalCode.PostalCode.Replace("'", "\\'") + "'," + newCityId + "," +
                                    newCountryId + ")");
                    insertComma = true;
                }

                sqlBuild.Append(";");

                // Insert all postal codes in one bulk op, to save roundtrips
                SwarmDb.GetDatabaseForAdmin().ExecuteAdminCommand(sqlBuild.ToString());
            }
        }
예제 #7
0
 public void AddVoter(Person person)
 {
     SwarmDb.GetDatabaseForWriting().CreateInternalPollVoter(this.Identity, person.Identity);
 }
예제 #8
0
 public static PositionAssignment FromIdentity(int positionAssignmentId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForReading().GetPositionAssignment(positionAssignmentId)));
 }
예제 #9
0
 public static PositionAssignment FromIdentityAggressive(int positionAssignmentId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForWriting().GetPositionAssignment(positionAssignmentId))); // "ForWriting" is intentional - avoids race conditions in Create()
 }
예제 #10
0
 public void AddDetail(int position, MeetingElectionCandidate candidate)
 {
     SwarmDb.GetDatabaseForWriting().CreateInternalPollVoteDetail(this.Identity, candidate.Identity, position);
 }
예제 #11
0
 public void Clear()
 {
     SwarmDb.GetDatabaseForWriting().ClearInternalPollVote(this.Identity);
 }
예제 #12
0
 static public MeetingElectionVote FromVerificationCode(string verificationCode)
 {
     return(FromBasic(SwarmDb.GetDatabaseForReading().GetInternalPollVote(verificationCode)));
 }
예제 #13
0
        public static People FilterPeopleToMatchAuthority(People people, Authority authority, int gracePeriod)
        {
            // First: If sysadmin, return the whole list uncensored.

            if (IsSystemAdministrator(authority))
            {
                return(people);
            }

            SwarmDb databaseRead = SwarmDb.GetDatabaseForReading();

            if (gracePeriod == -1)
            {
                gracePeriod = Membership.GracePeriod;
            }

            Dictionary <int, List <BasicMembership> > membershipTable =
                databaseRead.GetMembershipsForPeople(people.Identities, gracePeriod);
            Dictionary <int, int> geographyTable = databaseRead.GetPeopleGeographies(people.Identities);

            Dictionary <int, Person> clearedPeople = new Dictionary <int, Person>();

            // TODO: Add org admin role, able to see previous members that aren't anonymized yet

            // Clear by organization roles

            foreach (BasicPersonRole role in authority.OrganizationPersonRoles)
            {
                Dictionary <int, BasicOrganization> clearedOrganizations =
                    OrganizationCache.GetOrganizationHashtable(role.OrganizationId);

                foreach (Person person in people)
                {
                    // Is the organization cleared in this officer's role for this to-be-viewed member?

                    if (membershipTable.ContainsKey(person.Identity))
                    {
                        foreach (BasicMembership membership in membershipTable[person.Identity])
                        {
                            if (clearedOrganizations.ContainsKey(membership.OrganizationId)
                                &&
                                authority.HasPermission(Permission.CanSeePeople, membership.OrganizationId,
                                                        person.GeographyId, Flag.Default))
                            {
                                if (membership.Active ||
                                    (membership.Expires > DateTime.Now.AddDays(-gracePeriod) &&
                                     membership.Expires.AddDays(1) > membership.DateTerminated
                                     &&
                                     authority.HasPermission(Permission.CanSeeExpiredDuringGracePeriod,
                                                             membership.OrganizationId, person.GeographyId, Flag.Default)))
                                {
                                    clearedPeople[person.Identity] = person;
                                    break;
                                }
                            }
                        }
                    }

                    /* -- commented out. This means "does the current authority have Org Admin privileges over Person"?
                     * else if (CanSeeNonMembers)
                     * { //person isn't member anywhere
                     *  clearedPeople[person.Identity] = person;
                     * }*/
                }
            }


            // Clear by node roles:
            //
            // For each node role, check if each member is in a cleared geography AND a cleared organization.
            // If so, permit view of this member. (A person in a branch of a geographical area for organizations X and Z
            // should see only people of those organizations only on those nodes.)


            foreach (BasicPersonRole role in authority.LocalPersonRoles)
            {
                Dictionary <int, BasicGeography> clearedGeographies =
                    GeographyCache.GetGeographyHashtable(role.GeographyId);
                Dictionary <int, BasicOrganization> clearedOrganizations =
                    OrganizationCache.GetOrganizationHashtable(role.OrganizationId);

                foreach (Person person in people)
                {
                    // Is the node AND the organization cleared in this officer's role for this to-be-viewed member?

                    if (membershipTable.ContainsKey(person.Identity))
                    {
                        foreach (BasicMembership membership in membershipTable[person.Identity])
                        {
                            int organizationClear = 0;
                            int geographyClear    = 0;
                            if (clearedOrganizations.ContainsKey(membership.OrganizationId))
                            {
                                organizationClear = membership.OrganizationId;

                                if (clearedGeographies.ContainsKey(geographyTable[person.Identity]))
                                {
                                    geographyClear = geographyTable[person.Identity];
                                }

                                if (organizationClear > 0 &&
                                    geographyClear > 0
                                    &&
                                    authority.HasPermission(Permission.CanSeePeople, organizationClear, geographyClear,
                                                            Flag.Default))
                                {
                                    if (membership.Active ||
                                        (membership.Expires > DateTime.Now.AddDays(-gracePeriod) &&
                                         membership.Expires.AddDays(1) > membership.DateTerminated
                                         &&
                                         authority.HasPermission(Permission.CanSeeExpiredDuringGracePeriod,
                                                                 membership.OrganizationId, person.GeographyId, Flag.Default)))
                                    {
                                        clearedPeople[person.Identity] = person;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }


            // End: Assemble an array of the resulting cleared people

            People result = new People();

            foreach (Person clearedPerson in clearedPeople.Values)
            {
                result.Add(clearedPerson);
            }

            return(result);
        }
예제 #14
0
 public static Authority GetPersonAuthority(int personId)
 {
     return
         (Authority.FromBasic(SwarmDb.GetDatabaseForReading().GetPersonAuthority(Person.FromIdentity(personId))));
 }
예제 #15
0
        public static Person RequestActivistSignoffProcess(string eMail, string URL)
        {
            int personID = 0;

            int.TryParse(eMail, out personID);
            Person authenticatedUser = null;
            People candidatePeople   = null;
            bool   personIsActivist  = false;

            if (personID == 0)
            {
                BasicPerson[] people =
                    SwarmDb.GetDatabaseForReading().GetPeopleFromEmailPattern(eMail.ToLower().Replace("%", "").Trim());
                candidatePeople = People.FromArray(people);

                // if multiple people share same e-mail, suppose the last one registered is the one to change.
                foreach (Person p in candidatePeople)
                {
                    if (authenticatedUser == null || authenticatedUser.PersonId < p.PersonId && p.IsActivist)
                    {
                        authenticatedUser = p;
                    }
                }
            }
            else
            {
                candidatePeople = People.FromIdentities(new[] { personID });
                if (candidatePeople.Count > 0)
                {
                    authenticatedUser = candidatePeople[0];
                }
            }

            if (authenticatedUser == null)
            {
                return(null);
            }


            //TODO: Localize
            string mailbody = "";

            App_LocalResources.Authentication.Culture = CultureInfo.InvariantCulture;


            if (candidatePeople.Count == 1 && candidatePeople[0].IsActivist)
            {
                personIsActivist = true;
                Person p = candidatePeople[0];
                if (App_LocalResources.Authentication.Culture == CultureInfo.InvariantCulture)
                {
                    App_LocalResources.Authentication.Culture = CultureInfo.GetCultureInfo(p.PreferredCulture);
                }


                string encodedPasswordTicket =
                    SHA1.Hash(p.Identity.ToString(CultureInfo.InvariantCulture)).Replace(" ", "").Substring(0, 4) +
                    p.Identity;

                mailbody  = App_LocalResources.Authentication.RequestActivistSignoff_Mail_Preamble;
                mailbody += App_LocalResources.Authentication.RequestActivistSignoff_Mail_ClickOneLink;


                mailbody += "\r\n" + String.Format(URL, encodedPasswordTicket);
            }
            else
            {
                string links = "";
                foreach (Person p in candidatePeople)
                {
                    Memberships msList = p.GetMemberships();
                    if (msList.Count == 0 && p.IsActivist)
                    {
                        personIsActivist = true;
                        if (App_LocalResources.Authentication.Culture == CultureInfo.InvariantCulture)
                        {
                            App_LocalResources.Authentication.Culture = CultureInfo.GetCultureInfo(p.PreferredCulture);
                        }


                        string encodedPasswordTicket =
                            GenerateNewPasswordHash(p, p.Identity.ToString()).Replace(" ", "").Substring(0, 4) +
                            p.Identity;
                        links += "\r\n\r\n";
                        links += "#" + p.PersonId;

                        links += "\r\n" + String.Format(URL, encodedPasswordTicket);
                    }
                }

                mailbody  = App_LocalResources.Authentication.RequestActivistSignoff_Mail_Preamble;
                mailbody += App_LocalResources.Authentication.RequestActivistSignoff_Mail_ClickOneOfLinks;
                mailbody += links;
            }

            mailbody += App_LocalResources.Authentication.RequestActivistSignoff_Mail_Ending;

            if (personIsActivist)
            {
                authenticatedUser.SendNotice(App_LocalResources.Authentication.RequestActivistSignoff_Mail_Subject,
                                             mailbody, 1);
            }
            return(authenticatedUser);
        }
예제 #16
0
        public static ChangeAccountDataResult SetAccountInitialBalance(int accountId, string newInitialBalanceString)
        {
            try
            {
                AuthenticationData authData = GetAuthenticationDataAndCulture();
                FinancialAccount   account  = FinancialAccount.FromIdentity(accountId);

                if (!PrepareAccountChange(account, authData, false) || authData.CurrentOrganization.Parameters.FiscalBooksClosedUntilYear >= authData.CurrentOrganization.FirstFiscalYear)
                {
                    return(new ChangeAccountDataResult
                    {
                        Result = ChangeAccountDataOperationsResult.NoPermission
                    });
                }

                Int64 desiredInitialBalanceCents =
                    (Int64)
                    (Double.Parse(newInitialBalanceString,
                                  NumberStyles.AllowThousands | NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint,
                                  CultureInfo.CurrentCulture) * 100.0);

                Int64 currentInitialBalanceCents = account.GetDeltaCents(new DateTime(1900, 1, 1),
                                                                         new DateTime(authData.CurrentOrganization.FirstFiscalYear, 1, 1));

                Int64 deltaCents = desiredInitialBalanceCents - currentInitialBalanceCents;

                // Find or create "Initial Balances" transaction

                FinancialAccountRows testRows = FinancialAccountRows.ForOrganization(authData.CurrentOrganization,
                                                                                     new DateTime(1900, 1, 1), new DateTime(authData.CurrentOrganization.FirstFiscalYear, 1, 1));

                FinancialTransaction initialBalancesTransaction = null;

                foreach (FinancialAccountRow row in testRows)
                {
                    if (row.Transaction.Description == "Initial Balances")
                    {
                        initialBalancesTransaction = row.Transaction;
                        break;
                    }
                }

                if (initialBalancesTransaction == null)
                {
                    // create transaction

                    initialBalancesTransaction = FinancialTransaction.Create(authData.CurrentOrganization.Identity,
                                                                             new DateTime(authData.CurrentOrganization.FirstFiscalYear - 1, 12, 31), "Initial Balances");
                }

                Dictionary <int, Int64> recalcBase = initialBalancesTransaction.GetRecalculationBase();
                int equityAccountId = authData.CurrentOrganization.FinancialAccounts.DebtsEquity.Identity;

                if (!recalcBase.ContainsKey(accountId))
                {
                    recalcBase[accountId] = 0;
                }
                if (!recalcBase.ContainsKey(equityAccountId))
                {
                    recalcBase[equityAccountId] = 0;
                }

                recalcBase[accountId]       += deltaCents;
                recalcBase[equityAccountId] -= deltaCents;
                initialBalancesTransaction.RecalculateTransaction(recalcBase, authData.CurrentUser);
                return(new ChangeAccountDataResult
                {
                    Result = ChangeAccountDataOperationsResult.Changed,
                    NewData = (desiredInitialBalanceCents / 100.0).ToString("N2", CultureInfo.CurrentCulture)
                });
            }
            catch (Exception weirdException)
            {
                SwarmDb.GetDatabaseForWriting()
                .CreateExceptionLogEntry(DateTime.UtcNow, "AccountPlan-SetInitBalance", weirdException);

                throw;
            }
        }
예제 #17
0
        public static ParleyOptions ForParleyAttendee(ParleyAttendee attendee)
        {
            int[] parleyOptionIds = SwarmDb.GetDatabaseForReading().GetParleyAttendeeOptions(attendee.Identity);

            return(FromIdentities(parleyOptionIds));
        }
예제 #18
0
        public static ChangeAccountDataResult SetAccountBudget(int accountId, string budget)
        {
            try
            {
                AuthenticationData authData = GetAuthenticationDataAndCulture();
                FinancialAccount   account  = FinancialAccount.FromIdentity(accountId);

                if (!PrepareAccountChange(account, authData, false))
                {
                    return(new ChangeAccountDataResult
                    {
                        Result = ChangeAccountDataOperationsResult.NoPermission
                    });
                }

                Int64 newTreeBudget;
                budget = budget.Replace("%A0", "%20");
                // some very weird browser space-to-otherspace translation weirds out number parsing
                budget = HttpContext.Current.Server.UrlDecode(budget);

                if (budget.Trim().Length > 0 &&
                    Int64.TryParse(budget, NumberStyles.Currency, CultureInfo.CurrentCulture, out newTreeBudget))
                {
                    newTreeBudget *= 100; // convert to cents

                    int year = DateTime.Today.Year;
                    FinancialAccounts accountTree         = account.ThisAndBelow();
                    Int64             currentTreeBudget   = accountTree.GetBudgetSumCents(year);
                    Int64             currentSingleBudget = account.GetBudgetCents(year);
                    Int64             suballocatedBudget  = currentTreeBudget - currentSingleBudget;

                    Int64 newSingleBudget = newTreeBudget - suballocatedBudget;

                    account.SetBudgetCents(DateTime.Today.Year, newSingleBudget);

                    // Once we've set the budget, also update the "yearly result" budget.
                    // The "yearly result" budget isn't shown in the account plan, but is
                    // abstracted to "projected loss" or "projected gain" pseudobudgets.

                    int thisYear = DateTime.UtcNow.Year;
                    FinancialAccounts allProfitLossAccounts   = FinancialAccounts.ForOrganization(authData.CurrentOrganization);
                    Int64             newProfitLossProjection = allProfitLossAccounts.Where(queryAccount => queryAccount.Identity != authData.CurrentOrganization.FinancialAccounts.CostsYearlyResult.Identity).Sum(queryAccount => queryAccount.GetBudgetCents(thisYear));

                    authData.CurrentOrganization.FinancialAccounts.CostsYearlyResult.SetBudgetCents(thisYear, -newProfitLossProjection);

                    return(new ChangeAccountDataResult
                    {
                        Result = ChangeAccountDataOperationsResult.Changed,
                        NewData = (newTreeBudget / 100).ToString("N0", CultureInfo.CurrentCulture)
                    });
                }

                return(new ChangeAccountDataResult
                {
                    Result = ChangeAccountDataOperationsResult.Invalid
                });
            }
            catch (Exception weirdException)
            {
                // Exceptions are happening here in deployment ONLY. We're logging it to find which one and why.
                // TODO: This really needs to be in Logic. DO NOT DO NOT DO NOT call Database layer directly from Site layer.

                SwarmDb.GetDatabaseForWriting()
                .CreateExceptionLogEntry(DateTime.UtcNow, "AccountPlan-SetBudget", weirdException);

                throw;
            }
        }
예제 #19
0
 public static MeetingElection FromIdentity(int internalPollId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForReading().GetInternalPoll(internalPollId)));
 }
예제 #20
0
        public static MembershipEvents LoadAll()
        {
            // This is a very expensive op - heavy databasery and some five to ten seconds of execution time.

            // This function works in three steps. First, we load all people and build a hash of their geographies, genders.
            // Second, we load all memberships.
            // Third, we generate membership events from the membership and hash combo.

            // (and fourth, we sort the events by date)

            // In the person-gathering phase, we use BasicPerson in order to avoid the unneeded translation to Person.

            BasicPerson[] allPeople = SwarmDb.GetDatabaseForReading().GetAllPeople();

            Dictionary <int, int>          geoLookup       = new Dictionary <int, int>();
            Dictionary <int, PersonGender> genderLookup    = new Dictionary <int, PersonGender>();
            Dictionary <int, int>          birthYearLookup = new Dictionary <int, int>();

            foreach (BasicPerson person in allPeople)
            {
                geoLookup[person.Identity]       = person.GeographyId;
                genderLookup[person.Identity]    = person.IsMale ? PersonGender.Male : PersonGender.Female;
                birthYearLookup[person.Identity] = person.Birthdate.Year;
            }

            // Second phase, load all memberships

            BasicParticipation[] allParticipations = SwarmDb.GetDatabaseForReading().GetParticipations();

            // Third phase - for every membership, generate one or two membership events

            MembershipEvents result = new MembershipEvents();

            foreach (BasicParticipation membership in allParticipations)
            {
                int          geographyId = 1;
                int          birthYear   = 0;
                PersonGender gender      = PersonGender.Unknown;

                if (geoLookup.ContainsKey(membership.PersonId))
                {
                    geographyId = geoLookup[membership.PersonId];
                    gender      = genderLookup[membership.PersonId];
                    birthYear   = birthYearLookup[membership.PersonId];
                }

                result.Add(new MembershipEvent(membership.MemberSince, membership.PersonId, membership.OrganizationId,
                                               geographyId, birthYear, gender, 1));

                if (!membership.Active)
                {
                    TimeSpan safetyDelta = new TimeSpan(0);

                    // A few records in the database have had their memberships terminated at the exact time of creation. This means that sorting will
                    // be unpredictable, when it relies on the termination coming at a later time than the creation.

                    // To solve this, make sure they are more than five seconds apart.

                    if (membership.DateTerminated.Date == membership.MemberSince.Date)
                    // First simple check
                    {
                        if ((membership.DateTerminated - membership.MemberSince) < new TimeSpan(0, 0, 5))
                        {
                            safetyDelta = new TimeSpan(0, 0, 5);
                        }
                    }

                    result.Add(new MembershipEvent(membership.DateTerminated + safetyDelta,
                                                   membership.PersonId, membership.OrganizationId, geographyId,
                                                   birthYear, gender, -1));
                }
            }

            // Fourth - sort

            result.Sort(new MembershipEventSorter());

            return(result);
        }
예제 #21
0
 public InternalPollVoterStatus GetVoterStatus(Person person)
 {
     return(SwarmDb.GetDatabaseForReading().GetInternalPollVoterStatus(this.Identity, person.Identity));
 }
예제 #22
0
        private static void Main(string[] args)
        {
            testMode = false;

            UnixSignal[] killSignals =
            {
                new UnixSignal(Signum.SIGINT),
                new UnixSignal(Signum.SIGTERM)
            };

            BotLog.Write(0, "MainCycle", string.Empty);
            BotLog.Write(0, "MainCycle", "-----------------------------------------------");
            BotLog.Write(0, "MainCycle", string.Empty);

            if (args.Length > 0)
            {
                if (args[0].ToLower() == "test")
                {
/*
 *                  BotLog.Write(0, "MainCycle", "Running self-tests");
 *                  HeartBeater.Instance.Beat(heartbeatFile);  // Otherwise Heartbeater.Beat() will fail in various places
 *
 *                  testMode = true;
 *                  Console.WriteLine("Testing All Maintenance Processes (except membership-changing ones).");
 *                  PWLog.Write(PWLogItem.None, 0, PWLogAction.SystemTest, string.Empty, string.Empty);
 *
 *                  Console.WriteLine("\r\n10-second intervals:");
 *                  OnEveryTenSeconds();
 *                  Console.WriteLine("\r\nEvery minute:");
 *                  OnEveryMinute();
 *                  Console.WriteLine("\r\nEvery five minutes:");
 *                  OnEveryFiveMinutes();
 *                  Console.WriteLine("\r\nEvery hour:");
 *                  OnEveryHour();
 *                  Console.WriteLine("\r\nNoon:");
 *                  OnNoon();
 *                  Console.WriteLine("\r\nMidnight:");
 *                  OnMidnight();
 */

                    Console.WriteLine("Testing database access...");

                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).Name);
                    Console.WriteLine(SwarmDb.GetDatabaseForReading().GetPerson(1).PasswordHash);

                    Console.WriteLine("Creating OutboundComm...");

                    OutboundComm.CreateNotification(null, NotificationResource.System_Startup);

                    Console.WriteLine("Transmitting...");

                    OutboundComms comms = OutboundComms.GetOpen();

                    Console.WriteLine("{0} open items in outbound comms.", comms.Count);

                    foreach (OutboundComm comm in comms)
                    {
                        if (comm.TransmitterClass != "Swarmops.Utility.Communications.CommsTransmitterMail")
                        {
                            throw new NotImplementedException();
                        }

                        ICommsTransmitter transmitter = new CommsTransmitterMail();

                        OutboundCommRecipients recipients = comm.Recipients;
                        PayloadEnvelope        envelope   = PayloadEnvelope.FromXml(comm.PayloadXml);

                        foreach (OutboundCommRecipient recipient in recipients)
                        {
                            transmitter.Transmit(envelope, recipient.Person);
                        }
                    }


                    Console.Write("\r\nAll tests run. Waiting for mail queue to flush... ");
                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");
                    BotLog.Write(0, "MainCycle", "Exiting self-tests");
                    return;
                }

                if (args[0].ToLower() == "console")
                {
                    Console.WriteLine("\r\nRunning Swarmops-Backend in CONSOLE mode.\r\n");

                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------
                    // -------------------------------------------------------------------------------------

                    // -----------------------    INSERT ANY ONE-OFF ACTIONS HERE  -------------------------


                    Console.Write("\r\nWaiting for mail queue to flush... ");

                    while (!MailTransmitter.CanExit)
                    {
                        Thread.Sleep(50);
                    }

                    Console.WriteLine("done.");

                    return;
                }

                if (args[0].ToLower() == "rsm")
                {
                    Console.WriteLine("Testing character encoding: räksmörgås RÄKSMÖRGÅS");
                    return;
                }
            }

            /*
             * MailMessage message = new MailMessage();
             * message.From = new MailAddress(Strings.MailSenderAddress, Strings.MailSenderName);
             * message.To.Add (new MailAddress ("*****@*****.**", "Rick Falkvinge (Piratpartiet)"));
             * message.Subject = "Räksmörgåsarnas ékÖNÖMÏåvdëlnïng";
             * message.Body = "Hejsan hoppsan Räksmörgåsar.";
             * message.BodyEncoding = Encoding.Default;
             * message.SubjectEncoding = Encoding.Default;
             *
             * SmtpClient smtpClient = new SmtpClient ("localhost");
             * smtpClient.Credentials = null; // mono bug
             * smtpClient.Send (message);*/

            Console.WriteLine(" * Swarmops Backend starting");

            BotLog.Write(0, "MainCycle", "Backend STARTING");

            OutboundComm.CreateNotification(null, NotificationResource.System_Startup);

            // Checking for schemata upgrade

            DatabaseMaintenance.UpgradeSchemata();

            // Check for existence of installation ID. If not, create one. Warning: has privacy implications when communicated.

            if (Persistence.Key["SwarmopsInstallationId"] == string.Empty)
            {
                Persistence.Key["SwarmopsInstallationId"] = Guid.NewGuid().ToString();
            }

            DateTime cycleStartTime = DateTime.Now;

            int lastSecond = cycleStartTime.Second;
            int lastMinute = cycleStartTime.Minute;
            int lastHour   = cycleStartTime.Hour;

            bool exitFlag = false;

            while (!exitFlag) // exit is handled by signals handling at end of loop
            {
                BotLog.Write(0, "MainCycle", "Cycle Start");

                cycleStartTime = DateTime.Now;

                try
                {
                    OnEveryTenSeconds();

                    if (cycleStartTime.Second < lastSecond)
                    {
                        OnEveryMinute();

                        if (cycleStartTime.Minute % 5 == 0)
                        {
                            OnEveryFiveMinutes();
                        }
                    }

                    if (cycleStartTime.Minute < lastMinute)
                    {
                        OnEveryHour();

                        if (DateTime.Now.Hour == 10 && DateTime.Today.DayOfWeek == DayOfWeek.Tuesday)
                        {
                            OnTuesdayMorning();
                        }
                    }

                    if (cycleStartTime.Hour >= 12 && lastHour < 12)
                    {
                        OnNoon();
                    }

                    if (cycleStartTime.Hour < lastHour)
                    {
                        OnMidnight();
                    }
                }

                catch (Exception e)
                {
                    // Note each "OnEvery..." catches its own errors and sends Exception mails,
                    // so that failure in one should not stop the others from running. This particular
                    // code should never run.

                    ExceptionMail.Send(new Exception("Failed in swarmops-backend main loop", e), true);
                }

                lastSecond = cycleStartTime.Second;
                lastMinute = cycleStartTime.Minute;
                lastHour   = cycleStartTime.Hour;

                // Wait for a maximum of ten seconds

                while (DateTime.Now < cycleStartTime.AddSeconds(10) && !exitFlag)
                {
                    // block until a SIGINT or SIGTERM signal is generated, or one second has passed.
                    int signalIndex = UnixSignal.WaitAny(killSignals, 1000);

                    if (signalIndex < 1000)
                    {
                        exitFlag = true;
                        Console.WriteLine("Caught signal " + killSignals[signalIndex].Signum + ", exiting");
                        BotLog.Write(0, "MainCycle",
                                     "EXIT SIGNAL (" + killSignals[signalIndex].Signum + "), terminating backend");
                    }
                }
            }

            Console.WriteLine(" * Swarmops Backend stopping");
            BotLog.Write(0, "MainCycle", "BACKEND EXITING, sending backend-termination notices");

            /*
             * if (HeartBeater.Instance.WasKilled)
             * {
             *  // removed unconditional delete, cron job that restarts bot uses it to know that it is intentionally down.
             *  ExceptionMail.Send(new Exception("HeartBeater triggered restart of Swarmops Backend. Will commence after 800 seconds."), false);
             * }*/

            BotLog.Write(0, "MainCycle", "...done");

            /*
             * while (!MailTransmitter.CanExit)
             * {
             *  System.Threading.Thread.Sleep(50);
             * }*/

            Thread.Sleep(2000);
        }
예제 #23
0
 public static Ballot FromIdentity(int ballotId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForReading().GetBallot(ballotId)));
 }
예제 #24
0
 public static PayrollAdjustments ForSalary(Salary salary)
 {
     return(FromArray(SwarmDb.GetDatabaseForReading().GetPayrollAdjustments(salary)));
 }
예제 #25
0
 public void ClearCandidates()
 {
     SwarmDb.GetDatabaseForWriting().ClearBallotCandidates(Identity);
 }
예제 #26
0
 public static PayrollAdjustments ForPayrollItem(PayrollItem payrollItem)
 {
     return
         (FromArray(SwarmDb.GetDatabaseForReading()
                    .GetPayrollAdjustments(payrollItem, DatabaseCondition.OpenTrue)));
 }
예제 #27
0
 public void AddItem(string description, double amount)
 {
     SwarmDb.GetDatabaseForWriting().CreateOutboundInvoiceItem(Identity, description, amount);
 }
예제 #28
0
        public static Person RequestNewPasswordProcess(string eMail, string URL)
        {
            int personID = 0;

            int.TryParse(eMail, out personID);
            Person authenticatedUser = null;
            People candidatePeople   = null;

            if (personID == 0)
            {
                BasicPerson[] people =
                    SwarmDb.GetDatabaseForReading().GetPeopleFromEmailPattern(eMail.ToLower().Replace("%", "").Trim());
                candidatePeople = People.FromArray(people);

                // if multiple people share same e-mail, suppose the last one registered is the one to change.
                foreach (Person p in candidatePeople)
                {
                    if (authenticatedUser == null || authenticatedUser.PersonId < p.PersonId)
                    {
                        authenticatedUser = p;
                    }
                }
            }
            else
            {
                candidatePeople = People.FromIdentities(new[] { personID });
                if (candidatePeople.Count > 0)
                {
                    authenticatedUser = candidatePeople[0];
                }
            }

            if (authenticatedUser == null)
            {
                return(null);
            }

            string passwordTicket = CreateRandomPassword(EmailVerificationTicketLength);

            foreach (Person p in candidatePeople)
            {
                string encodedPasswordTicket = GenerateNewPasswordHash(p, passwordTicket);
                p.ResetPasswordTicket = encodedPasswordTicket + ";" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            }

            //TODO: Localize
            string mailbody = "";

            App_LocalResources.Authentication.Culture = CultureInfo.InvariantCulture;

            if (candidatePeople.Count == 1)
            {
                App_LocalResources.Authentication.Culture =
                    CultureInfo.GetCultureInfo(authenticatedUser.PreferredCulture);

                mailbody  = App_LocalResources.Authentication.RequestNewPassword_Mail_Preamble;
                mailbody += App_LocalResources.Authentication.RequestNewPassword_Mail_ClickOneLink;
                mailbody += "\r\n" + String.Format(URL, authenticatedUser.PersonId, passwordTicket);
            }
            else
            {
                string linksTot = "";
                foreach (Person p in candidatePeople)
                {
                    string links           = "";
                    int    membershipCount = 0;
                    if (App_LocalResources.Authentication.Culture == CultureInfo.InvariantCulture)
                    {
                        App_LocalResources.Authentication.Culture = CultureInfo.GetCultureInfo(p.PreferredCulture);
                    }

                    links += "\r\n\r\n";
                    links += "#" + p.PersonId;
                    links += " [Member of:";
                    Memberships msList = p.GetMemberships();
                    foreach (Membership ms in msList)
                    {
                        ++membershipCount;
                        links += " (" + ms.Organization.Name + "," + ms.MemberSince.ToString("yyyy-MM-dd") + ")";
                    }
                    links += "] ";
                    links += "\r\n" + String.Format(URL, p.PersonId, passwordTicket);
                    if (membershipCount > 0)
                    {
                        linksTot += links;
                    }
                }

                mailbody  = App_LocalResources.Authentication.RequestNewPassword_Mail_Preamble;
                mailbody += App_LocalResources.Authentication.RequestNewPassword_Mail_ClickOneOfLinks;
                mailbody += "\r\n" + linksTot;
            }

            mailbody += App_LocalResources.Authentication.RequestNewPassword_Mail_Ending;

            authenticatedUser.SendNotice(App_LocalResources.Authentication.RequestNewPassword_Mail_Subject, mailbody, 1);
            return(authenticatedUser);
        }
예제 #29
0
 static public Salaries ForOrganization(Organization organization, bool includeClosed)
 {
     return(FromArray(SwarmDb.GetDatabaseForReading().GetSalaries(organization,
                                                                  includeClosed? DatabaseCondition.None : DatabaseCondition.OpenTrue)));
 }
예제 #30
0
 public static Document FromIdentityAggressive(int documentId)
 {
     return(FromBasic(SwarmDb.GetDatabaseForWriting().GetDocument(documentId))); // "For writing" is intentional - bypasses a race condition in replication
 }