// Read existing stored values for token secrets & issuers private TokenSettingsFile ReadTokenSettingsFile() { try { // Attempt reading the file using (var reader = new StreamReader(Path.Combine(_config["ConfigFilePath"], JWT_CONFIG_FILENAME))) { return(JsonSerializer.Deserialize <TokenSettingsFile>(reader.ReadToEnd())); } } catch (IOException) { // If any errors, then regenerate the local secrets file // Generate values and serialize object var tokenSettings = new TokenSettingsFile() { Secret = PasswordUtils.GenerateSalt(128), Issuer = Convert.ToBase64String(PasswordUtils.GenerateSalt(64), Base64FormattingOptions.None), Audience = Convert.ToBase64String(PasswordUtils.GenerateSalt(64), Base64FormattingOptions.None) }; // Write new values to file if (!Directory.Exists(_config["ConfigFilePath"])) { Directory.CreateDirectory(_config["ConfigFilePath"]); } var file = File.Create(Path.Combine(_config["ConfigFilePath"], JWT_CONFIG_FILENAME)); using (var writer = new StreamWriter(file, Encoding.UTF8)) { writer.WriteLine(JsonSerializer.Serialize(tokenSettings)); return(tokenSettings); } } }
public async Task <ActionResult <UserDTO> > CreateUser([FromBody] UserLoginRequestDTO dto, CancellationToken ct) { if (dto == null) { return(BadRequest()); } if (!await _userSvc.CheckUsernameAvailableAsync(dto.Username, ct)) { var modelErrors = new ModelStateDictionary(); modelErrors.AddModelError("details", "That username is already in use."); return(Conflict(modelErrors)); } if (Validators.CheckForbiddenName(dto.Username)) { var modelErrors = new ModelStateDictionary(); modelErrors.AddModelError("details", "That username is forbidden or reserved for system use."); return(Conflict(modelErrors)); } var obj = _mapper.Map <User>(dto); obj.Id = Guid.NewGuid(); obj.Salt = PasswordUtils.GenerateSalt(); obj.Hash = PasswordUtils.GenerateHash(dto.Password, obj.Salt); obj = await _userSvc.AddUserAsync(obj, ct); return(CreatedAtAction(nameof(GetUser), new { id = obj.Id }, _mapper.Map <UserDTO>(obj))); }
public static UserAccount CreateNewUser() { var result = new UserAccount { UserId = Guid.NewGuid(), UserSecret = PasswordUtils.GeneratePassword(), Salt = PasswordUtils.GenerateSalt() }; return(result); }
public async Task <ActionResult <UserDTO> > UpdateUser(Guid id, [FromBody] UserUpdateDTO dto, CancellationToken ct) { var obj = await _userSvc.GetUserAsync(id, ct : ct); if (obj == null) { return(NotFound()); } obj.Salt = PasswordUtils.GenerateSalt(); obj.Hash = PasswordUtils.GenerateHash(dto.Password, obj.Salt); obj = await _userSvc.UpdateUserAsync(obj, ct); return(Ok(_mapper.Map <UserDTO>(obj))); }
public override async Task <User> UpdateAsync(User retrievedUser, User user) { if (!string.IsNullOrEmpty(user.Password)) { string salt = PasswordUtils.GenerateSalt(); string hashedPassword = PasswordUtils.HashPasswordWithSalt(user.Password, salt); user.Salt = salt; user.Password = hashedPassword; } else { user.Password = retrievedUser.Password; user.Salt = retrievedUser.Salt; } if (user.Created == DateTimeOffset.MinValue) { user.Created = retrievedUser.Created; } if (string.IsNullOrEmpty(user.Username)) { user.Username = retrievedUser.Username; } if (string.IsNullOrEmpty(user.DisplayName)) { user.DisplayName = retrievedUser.DisplayName; } var now = DateTime.UtcNow; user.LastUpdate = now; // After password update DbContext.Entry(retrievedUser).CurrentValues.SetValues(new { user.Username, user.Password, user.DisplayName, user.Salt }); await DbContext.SaveChangesAsync(); return(retrievedUser); }
public override async Task <User> InsertAsync(User user) { var defaultAvatarPath = Configuration.GetValue <string>("DefaultAvatar"); string originalPass = user.Password; string salt = PasswordUtils.GenerateSalt(); string hashedPass = PasswordUtils.HashPasswordWithSalt(originalPass, salt); var now = DateTimeOffset.UtcNow; user.Username = user.Username.Trim(); user.DisplayName = user.DisplayName.Trim(); user.Password = hashedPass; user.Salt = salt; user.Created = now; user.LastUpdate = now; var transaction = DbContext.Database.BeginTransaction(); await UserDatabase.AddAsync(user); await DbContext.SaveChangesAsync(); // create new avatar record var photo = new AvatarPhoto { UserId = user.Id, FileName = defaultAvatarPath }; DbContext.AvatarPhotos.Add(photo); await DbContext.SaveChangesAsync(); await transaction.CommitAsync(); // format output user.AvatarPhoto = photo; return(user); }
public UserDto Post([FromBody] UserDto userDto) { if (!userDto.IsValid()) { throw new HttpResponseException(HttpStatusCode.BadRequest); } using (var db = new CompAgriConnection()) { var previousUser = db.User.FirstOrDefault(u => (u.UserName != null && u.UserName == userDto.UserName) || (u.Email != null && u.Email == userDto.Email)); if (previousUser != null) { throw WebExceptionsFactory.GetUserDuplicatedException(); } var userBeforeSave = userDto.User(); userBeforeSave.PasswordSalt = PasswordUtils.GenerateSalt(); userBeforeSave.Password = PasswordUtils.HashPassword(userBeforeSave.Password, userBeforeSave.PasswordSalt); var user = db.User.Add(userBeforeSave); db.SaveChanges(); return(new UserDto(user)); } }
public EnrollmentResponse EnrollNewStudent(EnrollmentStudentRequest enrollmentStudentRequest) { using var connection = new SqlConnection(AppSettingsUtils.GetConnectionString()); using var command = new SqlCommand { Connection = connection }; connection.Open(); var transaction = connection.BeginTransaction(); command.Transaction = transaction; command.CommandText = "SELECT s.IdStudy FROM Studies s WHERE s.Name = @StudiesName"; command.Parameters.AddWithValue("StudiesName", enrollmentStudentRequest.Studies); var dataReader = command.ExecuteReader(); if (!dataReader.Read()) { throw new ResourceNotFoundException( $"Studies by name {enrollmentStudentRequest.Studies} does not exist in database"); } var idStudy = Parse(dataReader["IdStudy"].ToString()); dataReader.Close(); command.Parameters.Clear(); command.CommandText = "SELECT * FROM Enrollment E WHERE E.Semester = 1 AND E.IdStudy = @IdStudy"; command.Parameters.AddWithValue("IdStudy", idStudy); dataReader = command.ExecuteReader(); var enrollmentResponse = new EnrollmentResponse(); if (!dataReader.Read()) { dataReader.Close(); command.Parameters.Clear(); command.CommandText = @"INSERT INTO Enrollment(IdEnrollment, Semester, StartDate, IdStudy) OUTPUT INSERTED.IdEnrollment, INSERTED.Semester, INSERTED.StartDate, INSERTED.IdStudy VALUES((SELECT MAX(E.IdEnrollment) FROM Enrollment E) + 1, @Semester, @StartDate, @IdStudy);"; command.Parameters.AddWithValue("Semester", 1); command.Parameters.AddWithValue("StartDate", DateTime.Now); command.Parameters.AddWithValue("IdStudy", idStudy); enrollmentResponse.IdEnrollment = Parse(command.ExecuteScalar().ToString()); enrollmentResponse.Semester = Parse(command.Parameters["Semester"].Value.ToString()); enrollmentResponse.IdStudy = Parse(command.Parameters["IdStudy"].Value.ToString()); enrollmentResponse.StartDate = DateTime.Parse(command.Parameters["StartDate"].Value.ToString()).ToString("yyyy-MM-dd"); } else { enrollmentResponse.IdEnrollment = Parse(dataReader["IdEnrollment"].ToString()); enrollmentResponse.Semester = Parse(dataReader["Semester"].ToString()); enrollmentResponse.IdStudy = Parse(dataReader["IdStudy"].ToString()); enrollmentResponse.StartDate = DateTime.Parse(dataReader["StartDate"].ToString()).ToString("yyyy-MM-dd"); } dataReader.Close(); command.Parameters.Clear(); command.CommandText = "SELECT S.IndexNumber FROM Student S WHERE IndexNumber = @indexNumber"; command.Parameters.AddWithValue("indexNumber", enrollmentStudentRequest.Index); dataReader = command.ExecuteReader(); if (dataReader.Read()) { throw new BadRequestException("Student Index number not unique");; } dataReader.Close(); command.Parameters.Clear(); var salt = PasswordUtils.GenerateSalt(); command.CommandText = @"INSERT INTO Student(IndexNumber, FirstName, LastName, BirthDate, IdEnrollment, Password, Salt) VALUES (@IndexNumber, @FirstName, @LastName, @BirthDate, @IdEnrollment, @Password, @Salt)"; command.Parameters.AddWithValue("IndexNumber", enrollmentStudentRequest.Index); command.Parameters.AddWithValue("FirstName", enrollmentStudentRequest.FirstName); command.Parameters.AddWithValue("LastName", enrollmentStudentRequest.LastName); command.Parameters.AddWithValue("BirthDate", enrollmentStudentRequest.BirthDate); command.Parameters.AddWithValue("IdEnrollment", enrollmentResponse.IdEnrollment); command.Parameters.AddWithValue("Password", PasswordUtils.CreateSaltedPasswordHash(enrollmentStudentRequest.Password, salt)); command.Parameters.AddWithValue("Salt", salt); command.ExecuteNonQuery(); transaction.Commit(); return(enrollmentResponse); }
protected override void OnModelCreating(ModelBuilder model) { #region Model configuration // Set certain columns to be *case insensitive* model.Entity <User>() .Property(u => u.Username) .HasColumnType("TEXT COLLATE NOCASE"); model.Entity <SettingsEntry>() .Property(s => s.Key) .HasColumnType("TEXT COLLATE NOCASE"); // Set default values model.Entity <Slide>() .Property(s => s.Order) .ValueGeneratedNever() .HasDefaultValue(999); model.Entity <Slide>() .Property(s => s.DisplaySeconds) .ValueGeneratedNever() .HasDefaultValue(20); #endregion #region Settings seeding #endregion #region Users seeding // Generate an admin user with a default known password. var adminUserSalt = PasswordUtils.GenerateSalt(); model.Entity <User>().HasData( new User() { Id = Guid.NewGuid(), Username = "******", Salt = adminUserSalt, Hash = PasswordUtils.GenerateHash("letmeslaps", adminUserSalt) }); #endregion #region DateTimeOffset converter if (Database.ProviderName == "Microsoft.EntityFrameworkCore.Sqlite") { // NB: Taken from https://blog.dangl.me/archive/handling-datetimeoffset-in-sqlite-with-entity-framework-core/ // SQLite does not have proper support for DateTimeOffset via Entity Framework Core, see the limitations // here: https://docs.microsoft.com/en-us/ef/core/providers/sqlite/limitations#query-limitations // To work around this, when the Sqlite database provider is used, all model properties of type DateTimeOffset // use the DateTimeOffsetToBinaryConverter // Based on: https://github.com/aspnet/EntityFrameworkCore/issues/10784#issuecomment-415769754 // This only supports millisecond precision, but should be sufficient for most use cases. foreach (var entityType in model.Model.GetEntityTypes()) { var properties = entityType.ClrType.GetProperties().Where(p => p.PropertyType == typeof(DateTimeOffset) || p.PropertyType == typeof(DateTimeOffset?)); foreach (var property in properties) { model.Entity(entityType.Name) .Property(property.Name) .HasConversion(new DateTimeOffsetToBinaryConverter()); } } } #endregion }
public EnrollmentResponse EnrollNewStudentEntity(EnrollmentStudentRequest enrollmentStudentRequest) { var context = new StudentDbContext(); var studies = context.Studies .FirstOrDefault(stud => enrollmentStudentRequest.Studies.Equals(stud.Name)); if (studies == null) { throw new ResourceNotFoundException("Studies with name = " + enrollmentStudentRequest.Studies + " dont exist"); } var enrollment = context.Enrollment.FirstOrDefault(enroll => 1.Equals(enroll.Semester) && studies.IdStudy.Equals(enroll.IdStudy)); var enrollmentResponse = new EnrollmentResponse(); if (enrollment == null) { var enrollmentNew = new Enrollment { IdEnrollment = context.Enrollment.Select(enroll => enroll.IdEnrollment).OrderByDescending(i => i).First() + 1, Semester = 1, StartDate = DateTime.Now, IdStudy = studies.IdStudy }; context.Enrollment.Add(enrollmentNew); enrollmentResponse.IdEnrollment = enrollmentNew.IdEnrollment; enrollmentResponse.Semester = enrollmentNew.Semester; enrollmentResponse.IdStudy = enrollmentNew.IdStudy; enrollmentResponse.StartDate = enrollmentNew.StartDate.ToString("yyyy-MM-dd"); } else { enrollmentResponse.IdEnrollment = enrollment.IdEnrollment; enrollmentResponse.Semester = enrollment.Semester; enrollmentResponse.IdStudy = enrollment.IdStudy; enrollmentResponse.StartDate = enrollment.StartDate.ToString("yyyy-MM-dd"); } if (context.Student.Any(student => enrollmentStudentRequest.Index.Equals(student.IndexNumber))) { throw new BadRequestException("Student Index number not unique"); ; } var salt = PasswordUtils.GenerateSalt(); context.Student.Add(new Student { IndexNumber = enrollmentStudentRequest.Index, FirstName = enrollmentStudentRequest.FirstName, LastName = enrollmentStudentRequest.LastName, BirthDate = enrollmentStudentRequest.BirthDate, IdEnrollment = enrollmentResponse.IdEnrollment, Password = PasswordUtils.CreateSaltedPasswordHash(enrollmentStudentRequest.Password, salt), Salt = salt }); context.SaveChanges(); return(enrollmentResponse); }