public static void Execute(int electionId, IJobCancellationToken cancellationToken)
        {
            using (var db = new VotingDbContext())
            {
                Election election = db.Elections.Find(electionId);
                if (election == null)
                {
                    throw new ArgumentOutOfRangeException(nameof(electionId), "No election with such id");
                }

                if (election.DisableAutomaticEligibility)
                {
                    // Nothing to do
                    return;
                }

                using (var timetable = new TimetableDbContext())
                {
                    IEnumerable <ElectionEligibilityEntry> electionEntries =
                        EligibilityGenerator.GenerateElectionEntries(election, timetable.Users);
                    cancellationToken.ThrowIfCancellationRequested();

                    IEnumerable <PositionEligibilityEntry> positionEntries =
                        EligibilityGenerator.GeneratePositionEntries(election, timetable.Users, db);
                    cancellationToken.ThrowIfCancellationRequested();

                    // Note that we cannot dispose the timetable db context here
                    // since the queries are only "planned" yet and not actually executed

                    // Save election entries, only ones that do not exist in database
                    AddNewEntries(
                        electionEntries, db.ElectionEligibilityEntries,
                        (entry, set) => set.Find(entry.Username, entry.Election.Id)
                        );

                    cancellationToken.ThrowIfCancellationRequested();

                    // Save position entries, only ones that do not exist in database
                    AddNewEntries(
                        positionEntries, db.PositionEligibilityEntries,
                        (entry, set) => set.Find(entry.Username, entry.Position.Id)
                        );

                    cancellationToken.ThrowIfCancellationRequested();
                    db.SaveChanges();
                }
            }
        }
示例#2
0
 public DepartmentsRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
示例#3
0
 public TermsRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
 public ModulesRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
 public ClassroomsRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
 public SemestersRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
        public ActionResult LoginSso(string timetableToken, string returnUrl)
        {
            if (AuthHelpers.IsAuthenticated(User))
            {
                return(RedirectAfterLogin(true));
            }

            if (timetableToken == null)
            {
                // Store the return URL in session to use it when the user comes back
                if (!string.IsNullOrWhiteSpace(returnUrl))
                {
                    Session[ReturnUrlKey] = returnUrl;
                }

                return(RedirectToSso());
            }

            if (!Guid.TryParse(timetableToken, out Guid tokenGuid))
            {
                AuthHelpers.Logger.Information(
                    "SSO Fail: failed to parse token GUID '{token}' from {UserHostAddress} ",
                    timetableToken, Request.UserHostAddress
                    );

                return(FailCallback());
            }

            TimetableDbContext timetableDb = new TimetableDbContext();
            AuthToken          token       = timetableDb.AuthTokens.Find(tokenGuid);

            if (token == null || token.UserHostAddress != Request.UserHostAddress)
            {
                AuthHelpers.Logger.Information(
                    "SSO Fail: Token {Guid} not found or UserHostAddress ({UserHostAddress}) doesn't match",
                    tokenGuid, Request.UserHostAddress
                    );

                return(FailCallback());
            }

            AuthSession session = timetableDb.AuthSessions.Find(token.SessionGuid);

            if (session == null || session.ExpiresAt < DateTime.Now)
            {
                AuthHelpers.Logger.Information(
                    "SSO Fail: Session for token {Guid} not found or it has expired. UserHostAddress: {UserHostAddress}",
                    tokenGuid, Request.UserHostAddress
                    );

                return(FailCallback());
            }

            TimetableUserEntry user = new TimetableUserRepository(timetableDb)
                                      .GetByUsername(session.UserEmail);

            if (user == null || user.UserId != TimetableUserEntry.NormalizeUsernameToId(session.UserEmail))
            {
                AuthHelpers.Logger.Information(
                    "SSO Fail: Session for token {Guid} failed to match a timetable user. UserHostAddress: {UserHostAddress}",
                    tokenGuid, Request.UserHostAddress
                    );

                return(FailCallback());
            }

            // All good, sign in

            timetableDb.AuthTokens.Remove(token);
            timetableDb.SaveChanges();

            ClaimsIdentity identity = new ClaimsIdentity(
                new[]
            {
                // These 2 are required for default antiforgery provider
                new Claim(ClaimTypes.NameIdentifier, user.UserId),
                new Claim(
                    "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
                    "ASP.NET Identity",
                    "http://www.w3.org/2001/XMLSchema#string"
                    ),

                // Additional stuff
                new Claim(ClaimTypes.Role, user.IsStudentSupport ? Roles.StudentSupport : Roles.Student),
                new Claim(ClaimTypes.Name, user.Fullname),
                new Claim(AuthHelpers.TimetableSessionClaim, session.Guid.ToString())
            },
                DefaultAuthenticationTypes.ApplicationCookie
                );

            Session[FailedSsoAttemptsKey] = 0;
            HttpContext.GetOwinContext().Authentication.SignIn(
                new AuthenticationProperties
            {
                IsPersistent = true     // We validate on every request anyway, so prevent needless redirects
            },
                identity
                );

            AuthHelpers.Logger.Information(
                "SSO Success: token {Guid} was used for successful sign in by {UserId}. UserHostAddress: {UserHostAddress}",
                tokenGuid, user.UserId, Request.UserHostAddress
                );

            return(RedirectAfterLogin());
        }
 public Repository(TimetableDbContext dbContext)
 {
     _dbContext = dbContext;
 }
示例#9
0
 public TimetableUserRepository(TimetableDbContext db)
 {
     this.db = db;
 }
示例#10
0
 public LecturersRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
示例#11
0
 public UnitOfWork(TimetableDbContext dbContext)
 {
     _dbContext = dbContext;
 }
 public WeekdaysRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
示例#13
0
 public SubjectsRepository(TimetableDbContext dbContext) : base(dbContext)
 {
     _dbContext = dbContext;
 }
示例#14
0
        /// <summary>
        /// Configures the authentication system
        /// </summary>
        private static void ConfigureAuth(IAppBuilder app)
        {
            if (AppAuthConfiguration.Get().DebugMode)
            {
                // Fake login page with username only

                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath          = new PathString($"/{AuthHelpers.LoginPath}"),

                    Provider = new CookieAuthenticationProvider
                    {
                        OnValidateIdentity = context =>
                        {
                            if (context.Identity.Claims.All(claim => claim.Type != AuthHelpers.DebugModeClaim))
                            {
                                context.RejectIdentity();
                                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
                            }

                            return(Task.CompletedTask);
                        }
                    }
                });
            }
            else
            {
                // Real SSO mode

                app.UseCookieAuthentication(new CookieAuthenticationOptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath          = new PathString($"/{AuthHelpers.LoginPath}"),

                    ExpireTimeSpan    = TimeSpan.FromDays(30),
                    SlidingExpiration = true,

                    Provider = new CookieAuthenticationProvider
                    {
                        OnValidateIdentity = async context =>
                        {
                            if (context.Identity.Claims.Any(claim => claim.Type == AuthHelpers.DebugModeClaim))
                            {
                                context.RejectIdentity();
                                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
                                return;
                            }

                            Claim sessionGuidClaim = context.Identity.Claims
                                                     .FirstOrDefault(claim => claim.Type == AuthHelpers.TimetableSessionClaim);

                            if (sessionGuidClaim == null)
                            {
                                context.RejectIdentity();
                                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
                                return;
                            }

                            TimetableDbContext timetableDb = new TimetableDbContext();
                            AuthSession session            =
                                await timetableDb.AuthSessions.FindAsync(new Guid(sessionGuidClaim.Value));

                            if (session == null || session.ExpiresAt < DateTime.Now)
                            {
                                context.RejectIdentity();
                                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
                                return;
                            }

                            TimetableUserEntry user = await new TimetableUserRepository(timetableDb)
                                                      .GetByUsernameAsync(session.UserEmail);

                            if (user == null || user.UserId != context.Identity.GetUserId())
                            {
                                context.RejectIdentity();
                                context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
                            }
                        }
                    }
                });
            }
        }
        public static void Execute(int electionId, IJobCancellationToken cancellationToken)
        {
            TimetableDbContext timetableDb = new TimetableDbContext();
            VotingDbContext    db          = new VotingDbContext();

            Election election = db.Elections.Find(electionId);

            if (election == null)
            {
                throw new ArgumentOutOfRangeException(nameof(electionId), "No election with such id");
            }

            if (election.Type != ElectionType.CourseRepresentative)
            {
                throw new Exception("Election must be of type " + ElectionType.CourseRepresentative);
            }

            if (!election.PositionGenerationInProcess)
            {
                throw new Exception($"Election {election.Name} is not pending position generation");
            }

            // Generate the list as it is intended to be now
            List <RepresentativePositionData> desiredPositionDatas = timetableDb.Users
                                                                     .WhereIsStudentActive()
                                                                     .Select(entry => new { entry.ProgrammeName, entry.ExpectedGraduationYearString })
                                                                     .Distinct()
                                                                     .AsEnumerable()
                                                                     .Select(combination =>
            {
                var data = new RepresentativePositionData
                {
                    ProgrammeName = combination.ProgrammeName,
                    ExpectedGraduationYearString = combination.ExpectedGraduationYearString,
                    PositionCommon = new VotablePosition {
                        Election = election
                    }
                };

                data.SetPositionName();

                return(data);
            })
                                                                     .ToList();

            // Get the current positions in DB
            List <RepresentativePositionData>       matchedDesiredDatas = new List <RepresentativePositionData>();
            IQueryable <RepresentativePositionData> positionsDataFromDb = db.RepresentativePositionData
                                                                          .Where(data => data.PositionCommon.ElectionId == electionId);

            foreach (RepresentativePositionData existingPositionData in positionsDataFromDb)
            {
                RepresentativePositionData matchingDesiredData = desiredPositionDatas.FirstOrDefault(desiredData =>
                                                                                                     existingPositionData.ProgrammeName == desiredData.ProgrammeName &&
                                                                                                     existingPositionData.ExpectedGraduationYearString == desiredData.ExpectedGraduationYearString
                                                                                                     );

                if (matchingDesiredData != null)
                {
                    // Found matching entry. Apply the position name in case the naming logic changed
                    existingPositionData.PositionCommon.HumanName = matchingDesiredData.PositionCommon.HumanName;
                    matchedDesiredDatas.Add(matchingDesiredData);
                }
                else
                {
                    // Did not match - no longer needed
                    db.RepresentativePositionData.Remove(existingPositionData);
                }
            }

            // Add the new positions (that didn't match existing) to the db
            db.RepresentativePositionData.AddRange(desiredPositionDatas.Except(matchedDesiredDatas));

            // Make sure we are allowed to submit our changes
            cancellationToken.ThrowIfCancellationRequested();

            // We are done
            election.PositionGenerationInProcess = false;
            db.SaveChanges();
        }