Пример #1
0
 public AcademicController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context            = context;
     _studentServices    = studentServices;
     _systemServices     = systemServices;
     _studentCredentials = new StudentCredential(context, studentServices, systemServices);
 }
Пример #2
0
 public ExamCardController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context           = context;
     _studentServices   = studentServices;
     studentCredentials = new StudentCredential(_context, studentServices, systemServices);
     _financeUtilities  = new FinanceController(context, studentServices, systemServices);
 }
Пример #3
0
 public HostelBookingController(UnisolAPIdbContext context, IStudentServices studentServices,
                                ISystemServices systemServices, IConfiguration configuration)
 {
     _context           = context;
     _systemServices    = systemServices;
     _configuration     = configuration;
     _studentServices   = studentServices;
     studentCredentials = new StudentCredential(_context, studentServices, systemServices);
 }
Пример #4
0
 public UnitsController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context           = context;
     _studentServices   = studentServices;
     _systemServices    = systemServices;
     studentCredentials = new StudentCredential(context, studentServices, systemServices);
     campusDetails      = new CampusDetails(context);
     _financeUtilities  = new FinanceController(context, studentServices, systemServices);
 }
        public Campus360AcademicsController(UnisolAPIdbContext context, IPortalApiProxy portalProxy, IStudentServices studentServices, ISystemServices systemServices)
        {
            _context           = context;
            studentCredentials = new StudentCredential(context, studentServices, systemServices);
            _studentServices   = studentServices;
            _systemServices    = systemServices;

            campusDetails = new CampusDetails(context);
            _portalProxy  = portalProxy;
        }
Пример #6
0
        private async Task <IActionResult> HandleUpstreamFailoverAsync(StudentCredential credential, string successMessage, string failMessage, ILogger log)
        {
            log.LogWarning("Experiencing issues with upstream service.");
            DataAccessResult <StudentCredential> credentialFetchResult = await dataService.GetCredentialAsync(credential.StudentId);

            if (credentialFetchResult.Success)
            {
                if (credential.PasswordHash.Equals(credentialFetchResult.Resource.PasswordHash, StringComparison.Ordinal))
                {
                    string token = tokenService.CreateToken(credential.StudentId);
                    return(new OkObjectResult(new BackendResult <AccessToken>(true, AccessToken.CompletedToken(token), successMessage)));
                }
                else
                {
                    return(new UnauthorizedObjectResult(new BackendResult <AccessToken>(locService.GetString("CredentialErrorCannotSignIn"))));
                }
            }
            else
            {
                return(new UnauthorizedObjectResult(new BackendResult <AccessToken>(failMessage)));
            }
        }
Пример #7
0
 public void DecryptCredential(StudentCredential credential)
 {
     if (credential.Iv == null)
     {
         throw new ArgumentException("Missing IV in provided credential.");
     }
     using (Aes aes = Aes.Create())
     {
         aes.Key = key;
         aes.IV  = Convert.FromBase64String(credential.Iv);
         using (var encryptedStream = new MemoryStream(Convert.FromBase64String(credential.PasswordHash)))
         {
             using (var cryptoStream = new CryptoStream(encryptedStream, aes.CreateDecryptor(), CryptoStreamMode.Read))
             {
                 using (var reader = new StreamReader(cryptoStream))
                 {
                     credential.PasswordHash = reader.ReadToEnd();
                 }
             }
         }
     }
     credential.Iv = null;
 }
Пример #8
0
 public void EncryptCredential(StudentCredential credential)
 {
     if (credential.Iv != null)
     {
         throw new InvalidOperationException("IV is not empty. Possibly already encrypted.");
     }
     using (Aes aes = Aes.Create())
     {
         aes.Key       = key;
         credential.Iv = Convert.ToBase64String(aes.IV);
         using (var encryptedStream = new MemoryStream())
         {
             using (var cryptoStream = new CryptoStream(encryptedStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
             {
                 using (var writer = new StreamWriter(cryptoStream))
                 {
                     writer.Write(credential.PasswordHash);
                 }
             }
             credential.PasswordHash = Convert.ToBase64String(encryptedStream.ToArray());
         }
     }
 }
Пример #9
0
        public async Task <DataRequestResult <AccessToken> > SignInAsync(StudentCredential credential, bool createAccount = false)
        {
            _ = credential?.StudentId ?? throw new InvalidOperationException("User credential is not yet configured.");
            _ = credential?.PasswordHash ?? throw new InvalidOperationException("User credential is not yet configured.");

            try
            {
                HttpResponseMessage response = await client.PostAsync($"signIn/{createAccount}", new JsonStringContent(credential));

                if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Accepted)
                {
                    var result = await response.Content.ReadAsJsonObjectAsync <BackendResult <AccessToken> >();

                    credentialService.Token = result.Resource.Token;
                    return(new DataRequestResult <AccessToken>(result.Resource, result.Message));
                }
                else
                {
                    BackendRequestFailedException exception;
                    if (response.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        exception = new BackendAuthenticationFailedException("Request failed due to incorrect credentials. Endpoint: signIn.");
                    }
                    else
                    {
                        exception = new BackendRequestFailedException($"Request failed due to an unexpected response status {response.StatusCode}. Endpoint: signIn.");
                    }
                    exception.DisplayMessage = await GetBackendMessageAsync(response.Content);

                    throw exception;
                }
            }
            catch (Exception ex) when(ex is HttpRequestException || ex is TaskCanceledException)
            {
                throw GetDefaultException($"signIn", ex);
            }
        }
Пример #10
0
 public ElectionsController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     studentCredentials = new StudentCredential(context, studentServices, systemServices);
 }
Пример #11
0
 public TranscriptController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemRepository)
 {
     _context          = context;
     studentCredential = new StudentCredential(context, studentServices, systemRepository);
 }
Пример #12
0
 public FinanceController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context           = context;
     studentCredentials = new StudentCredential(_context, studentServices, systemServices);
 }
Пример #13
0
 public async Task <DataAccessResult> SetCredentialAsync(StudentCredential credential)
 {
     encryptionService.EncryptCredential(credential);
     return(await SetResourceAsync(credential));
 }
Пример #14
0
        public async Task <IActionResult> RunPost(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "Calendar")] HttpRequest req,
            [UserIdentity] string?username,
            ILogger log)
        {
            if (username == null)
            {
                return(new UnauthorizedResult());
            }

            DataAccessResult <StudentInfo> userFetchResult = await dataService.GetStudentInfoAsync(username);

            StudentInfo?info = null;

            if (userFetchResult.Success)
            {
                info = userFetchResult.Resource;
            }
            else if (userFetchResult.StatusCode == 404)
            {
                DataAccessResult <StudentCredential> credentialFetchResult = await dataService.GetCredentialAsync(username);

                if (credentialFetchResult.Success)
                {
                    try
                    {
                        StudentCredential credential    = credentialFetchResult.Resource;
                        SignInContext     signInContext = await client.SignInAsync(credential.StudentId, credential.PasswordHash);

                        info = await client.GetStudentInfoAsync(signInContext);
                    }
                    catch (Exception ex)
                    {
                        log.LogError(ex, "Failed to fetch sign in or fetch user info from upstream.");
                    }
                }
                else if (credentialFetchResult.StatusCode == 404)
                {
                    return(new UnauthorizedResult());
                }
                else
                {
                    log.LogError("Failed to fetch user credential. Status {statusCode}", credentialFetchResult.StatusCode);
                }
            }
            else
            {
                log.LogError("Failed to fetch user info from database. Status {statusCode}", userFetchResult.StatusCode);
            }

            if (info == null)
            {
                return(new ObjectResult(new BackendResult <CalendarSubscription>(locService.GetString("ServiceErrorCannotAddCalendarSub")))
                {
                    StatusCode = 503
                });
            }

            info.CalendarSubscriptionId = Guid.NewGuid().ToString();
            DataAccessResult userUpdateResult = await dataService.SetStudentInfoAsync(info);

            if (userUpdateResult.Success)
            {
                return(new OkObjectResult(new BackendResult <CalendarSubscription>(new CalendarSubscription(info.CalendarSubscriptionId))));
            }
            else
            {
                log.LogError("Failed to update user info. Status {statusCode}", userUpdateResult.StatusCode);
                return(new ObjectResult(new BackendResult <CalendarSubscription>(locService.GetString("ServiceErrorCannotAddCalendarSub")))
                {
                    StatusCode = 503
                });
            }
        }
Пример #15
0
 public OnlineReportingController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context           = context;
     _studentServices   = studentServices;
     studentCredentials = new StudentCredential(context, studentServices, systemServices);
 }
Пример #16
0
 public LibraryController(LibraryAPIdbContext libraryContext, UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _libraryContext    = libraryContext;
     studentCredentials = new StudentCredential(context, studentServices, systemServices);
     library            = new Library(libraryContext);
 }
Пример #17
0
 public DatabaseUtilitiesController(UnisolAPIdbContext context, IStudentServices studentServices, ISystemServices systemServices)
 {
     _context           = context;
     _studentServices   = studentServices;
     studentCredentials = new StudentCredential(_context, studentServices, systemServices);
 }
Пример #18
0
        public async Task HandleRequestAsync <T>(
            string username,
            Func <IDataAccessService, Task <DataAccessResult <T> > > databaseFetchTask,
            Func <IUcquClient, SignInContext, Task <T> > clientFetchTask,
            Func <IDataAccessService, T, Task <DataAccessResult> > updateTask,
            Func <T?, T, bool> shouldUpdate,
            Func <T?, T, Task>?updateCompleteCallback,
            ILogger log)
            where T : class, IStatusResource
        {
            // Fetch new version.
            Task <DataAccessResult <T> > oldFetchTask = databaseFetchTask(dataService);
            RecordStatus newStatus = RecordStatus.UpToDate;
            DataAccessResult <StudentCredential> credentialFetchResult = await dataService.GetCredentialAsync(username);

            T?newResource = default(T);

            if (credentialFetchResult.Success)
            {
                // Got credential.
                StudentCredential credential = credentialFetchResult.Resource;
                try
                {
                    SignInContext signInContext = await client.SignInAsync(credential.StudentId, credential.PasswordHash);

                    if (signInContext.IsValid)
                    {
                        // OK.
                        newResource = await clientFetchTask(client, signInContext);
                    }
                    else
                    {
                        // User changed password. Mark stale.
                        newStatus = RecordStatus.StaleAuthError;
                    }
                }
                catch (Exception ex)
                {
                    // New resource fetch failure. Mark stale.
                    log.LogError(ex, "Failed to sign in or fetch resource from upstream. Resource type {resourceType}", typeof(T));
                    newStatus = RecordStatus.StaleUpstreamError;
                }
            }
            else if (credentialFetchResult.StatusCode == 404)
            {
                // Credential lost. Mark stale.
                log.LogWarning("Credential not found. Resource type {resourceType}", typeof(T));
                newStatus = RecordStatus.StaleAuthError;
            }
            else
            {
                // Data access error. Skip this refresh.
                log.LogError("Failed to fetch credential. Resource type {resourceType}. Status {statusCode}", typeof(T), credentialFetchResult.StatusCode);
                return;
            }
            // End new version fetch.
            // As of now, either new version contains value, or stale status determined.

            // Fetch old version.
            T?oldResource = default(T);
            DataAccessResult <T> oldFetchResult = await oldFetchTask;

            if (oldFetchResult.Success)
            {
                // OK.
                oldResource = oldFetchResult.Resource;
            }
            else if (oldFetchResult.StatusCode != 404)
            {
                // Data access error.
                log.LogError("Failed to fetch resource from database. Resource type {resourceType}. Status {statusCode}", typeof(T), oldFetchResult.StatusCode);
                return;
            }
            // End old version fetch.
            // As of now, either old version contains value, or an old version really does not exist.

            // Compare and update.
            if (newResource == null && oldResource == null)
            {
                // Both new and old resources are missing. Skip for this time.
                log.LogWarning("Update skipped because both old and new resources are missing. Resource type {resourceType}.", typeof(T));
                return;
            }
            else if (newResource == null)
            {
                // New resource cannot be fetched. Update stale flag.
                oldResource !.RecordStatus = newStatus;
                DataAccessResult updateResult = await updateTask(dataService, oldResource);

                if (!updateResult.Success)
                {
                    log.LogError("Failed to update database. Resource type {resourceType}. Status {statusCode}", typeof(T), updateResult.StatusCode);
                }
                return;
            }
            else if (shouldUpdate(oldResource, newResource))
            {
                // Caller determined that the resource should be updated.
                DataAccessResult updateResult = await updateTask(dataService, newResource);

                if (updateResult.Success)
                {
                    if (updateCompleteCallback != null)
                    {
                        try
                        {
                            await updateCompleteCallback(oldResource, newResource);
                        }
                        catch (Exception ex)
                        {
                            log.LogWarning(ex, "Update completion callback ran into an error.");
                        }
                    }
                }
                else
                {
                    log.LogError("Failed to update database. Resource type {resourceType}. Status {statusCode}", typeof(T), updateResult.StatusCode);
                }
                return;
            }
            else if (oldResource != null && oldResource.RecordStatus != RecordStatus.UpToDate)
            {
                // Caller opted to not update, but stale flag has to be cleared.
                oldResource.RecordStatus = RecordStatus.UpToDate;
                DataAccessResult updateResult = await updateTask(dataService, oldResource);

                if (!updateResult.Success)
                {
                    log.LogError("Failed to update database. Resource type {resourceType}. Status {statusCode}", typeof(T), updateResult.StatusCode);
                }
                return;
            }
        }
Пример #19
0
 public CoursesController(IStudentServices studentServices, UnisolAPIdbContext context, ISystemServices systemService)
 {
     _studentServices    = studentServices;
     _context            = context;
     _studentCredentials = new StudentCredential(_context, studentServices, systemService);
 }