Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Fix/xxxx-updateDependencies
  • Hotfix/0071-fixResourceCreate
  • Hotfix/1035-fixResourceApi
  • Hotfix/1360-databaseScaffolding
  • Hotfix/1383-topLevel
  • Hotfix/1383-topLevelAlternative
  • Hotfix/1433-defaultQuota
  • Hotfix/1796-projectDdos
  • Hotfix/2087-efNet6
  • Hotfix/64-releaseUDE
  • Hotfix/73-fixResourceCreateRDS
  • Issue/1321-pidEnquiryOverhaul
  • Issue/1788-extractionCronjob
  • Issue/1866-ExtendResourceTypeConfigurationTUDo
  • Issue/1867-addNewResourceTypes
  • Issue/1877-ExtendResourceTypeConfigurationNRWFHs
  • Issue/1878-addNewResourceTypes
  • Issue/1910-MigrationtoNET6.0
  • Issue/1913-ModificationsResourceMetadata
  • Issue/1951-quotaImplementation
  • Issue/1999-gitlabResourcesLib
  • Issue/2072-wormResourceType
  • Issue/2101-gitLabResTypeUi
  • Issue/2102-gitLabResTypeRCV
  • Issue/2183-kpiGeneratorResource
  • Issue/2221-projectDateCreated
  • Issue/2222-resourceDateCreated
  • Issue/2278-gitlabToS
  • Issue/2287-guestRole
  • Issue/2309-docs
  • Issue/2364-testingKpiParser
  • Issue/2449-GuidPidSlugToProjectSettings
  • Issue/3003-stsInstitute
  • Issues/0028-maxQuotaFix
  • Product/1100-fdsS3
  • Product/1149-dfnaai
  • Product/1154-resourceTypeDefinition
  • Product/1188-LoggingExtended
  • Product/1287-dotnet5Sharepoint
  • Product/1414-fhPrivileges
  • Product/1470-migrationForArchiving
  • Product/1573-ReadOnlyResources
  • Product/1629-onboardingOtherUniversities
  • Product/202-userInvitation
  • Product/407-net5migration
  • Product/704-basicReporting
  • Product/789-userContactEmail
  • Product/903-ApiTokens
  • Sprint/2020-20
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-04
  • Sprint/2021-05
  • Sprint/2021-08
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-15
  • Sprint/2021-19
  • Sprint/2022-01
  • Test/xxxx-pipelineTriggers
  • Topic/1051-basicReporting
  • Topic/1125-apiTokens
  • Topic/1159-rtdApi
  • Topic/1221-LogginExtendedNew
  • Topic/1221-LoggingExtended
  • Topic/1226-databaseLibraryMigration
  • Topic/1278-dfnAAI
  • Topic/1286-dotnet5Database
  • Topic/1292-FdsS3
  • Topic/1294-contactChangeFunctionality
  • Topic/1425-fhPrivileges
  • Topic/1453-userInvitation
  • Topic/1556-migrationForArchiving
  • Topic/1597-AddArchiveFlagInResourceObject
  • Topic/1711-extendResourceTypeConfiguration
  • Topic/1714-newResourceTypesUDE
  • dev
  • gitkeep
  • master
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.12.1
  • v1.13.0
  • v1.14.0
  • v1.15.0
  • v1.15.1
  • v1.16.0
  • v1.17.0
  • v1.18.0
  • v1.19.0
  • v1.2.0
  • v1.2.1
  • v1.2.2
  • v1.20.0
  • v1.21.0
  • v1.22.0
  • v1.22.1
  • v1.22.2
  • v1.23.0
  • v1.24.0
  • v1.25.0
  • v1.25.1
  • v1.26.0
  • v1.27.0
  • v1.27.1
  • v1.28.0
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.5.1
  • v1.6.0
  • v1.7.0
  • v1.8.0
  • v1.9.0
  • v2.0.0
  • v2.0.1
  • v2.1.0
  • v2.1.1
  • v2.10.0
  • v2.10.1
  • v2.11.0
  • v2.11.1
  • v2.12.0
  • v2.12.1
  • v2.13.0
  • v2.14.0
  • v2.15.0
  • v2.16.0
  • v2.16.1
  • v2.16.2
  • v2.17.0
  • v2.18.0
  • v2.19.0
  • v2.19.1
  • v2.2.0
  • v2.2.1
  • v2.20.0
  • v2.22.0
  • v2.3.0
  • v2.4.0
  • v2.4.1
  • v2.5.0
  • v2.6.0
  • v2.7.0
  • v2.7.1
  • v2.7.2
  • v2.7.3
  • v2.8.0
  • v2.9.0
  • v2.9.1
154 results

Target

Select target project
  • coscine/backend/libraries/database
1 result
Select Git revision
  • Fix/xxxx-updateDependencies
  • Hotfix/0071-fixResourceCreate
  • Hotfix/1035-fixResourceApi
  • Hotfix/1360-databaseScaffolding
  • Hotfix/1383-topLevel
  • Hotfix/1383-topLevelAlternative
  • Hotfix/1433-defaultQuota
  • Hotfix/1796-projectDdos
  • Hotfix/2087-efNet6
  • Hotfix/64-releaseUDE
  • Hotfix/73-fixResourceCreateRDS
  • Issue/1321-pidEnquiryOverhaul
  • Issue/1788-extractionCronjob
  • Issue/1866-ExtendResourceTypeConfigurationTUDo
  • Issue/1867-addNewResourceTypes
  • Issue/1877-ExtendResourceTypeConfigurationNRWFHs
  • Issue/1878-addNewResourceTypes
  • Issue/1910-MigrationtoNET6.0
  • Issue/1913-ModificationsResourceMetadata
  • Issue/1951-quotaImplementation
  • Issue/1999-gitlabResourcesLib
  • Issue/2072-wormResourceType
  • Issue/2101-gitLabResTypeUi
  • Issue/2102-gitLabResTypeRCV
  • Issue/2183-kpiGeneratorResource
  • Issue/2221-projectDateCreated
  • Issue/2222-resourceDateCreated
  • Issue/2278-gitlabToS
  • Issue/2287-guestRole
  • Issue/2309-docs
  • Issue/2364-testingKpiParser
  • Issue/2449-GuidPidSlugToProjectSettings
  • Issue/3003-stsInstitute
  • Issues/0028-maxQuotaFix
  • Product/1100-fdsS3
  • Product/1149-dfnaai
  • Product/1154-resourceTypeDefinition
  • Product/1188-LoggingExtended
  • Product/1287-dotnet5Sharepoint
  • Product/1414-fhPrivileges
  • Product/1470-migrationForArchiving
  • Product/1573-ReadOnlyResources
  • Product/1629-onboardingOtherUniversities
  • Product/202-userInvitation
  • Product/407-net5migration
  • Product/704-basicReporting
  • Product/789-userContactEmail
  • Product/903-ApiTokens
  • Sprint/2020-20
  • Sprint/2020-22
  • Sprint/2021-01
  • Sprint/2021-03
  • Sprint/2021-04
  • Sprint/2021-05
  • Sprint/2021-08
  • Sprint/2021-10
  • Sprint/2021-11
  • Sprint/2021-15
  • Sprint/2021-19
  • Sprint/2022-01
  • Test/xxxx-pipelineTriggers
  • Topic/1051-basicReporting
  • Topic/1125-apiTokens
  • Topic/1159-rtdApi
  • Topic/1221-LogginExtendedNew
  • Topic/1221-LoggingExtended
  • Topic/1226-databaseLibraryMigration
  • Topic/1278-dfnAAI
  • Topic/1286-dotnet5Database
  • Topic/1292-FdsS3
  • Topic/1294-contactChangeFunctionality
  • Topic/1425-fhPrivileges
  • Topic/1453-userInvitation
  • Topic/1556-migrationForArchiving
  • Topic/1597-AddArchiveFlagInResourceObject
  • Topic/1711-extendResourceTypeConfiguration
  • Topic/1714-newResourceTypesUDE
  • dev
  • gitkeep
  • master
  • v1.0.0
  • v1.1.0
  • v1.10.0
  • v1.11.0
  • v1.12.0
  • v1.12.1
  • v1.13.0
  • v1.14.0
  • v1.15.0
  • v1.15.1
  • v1.16.0
  • v1.17.0
  • v1.18.0
  • v1.19.0
  • v1.2.0
  • v1.2.1
  • v1.2.2
  • v1.20.0
  • v1.21.0
  • v1.22.0
  • v1.22.1
  • v1.22.2
  • v1.23.0
  • v1.24.0
  • v1.25.0
  • v1.25.1
  • v1.26.0
  • v1.27.0
  • v1.27.1
  • v1.28.0
  • v1.3.0
  • v1.4.0
  • v1.5.0
  • v1.5.1
  • v1.6.0
  • v1.7.0
  • v1.8.0
  • v1.9.0
  • v2.0.0
  • v2.0.1
  • v2.1.0
  • v2.1.1
  • v2.10.0
  • v2.10.1
  • v2.11.0
  • v2.11.1
  • v2.12.0
  • v2.12.1
  • v2.13.0
  • v2.14.0
  • v2.15.0
  • v2.16.0
  • v2.16.1
  • v2.16.2
  • v2.17.0
  • v2.18.0
  • v2.19.0
  • v2.19.1
  • v2.2.0
  • v2.2.1
  • v2.20.0
  • v2.22.0
  • v2.3.0
  • v2.4.0
  • v2.4.1
  • v2.5.0
  • v2.6.0
  • v2.7.0
  • v2.7.1
  • v2.7.2
  • v2.7.3
  • v2.8.0
  • v2.9.0
  • v2.9.1
154 results
Show changes
Commits on Source (5)
......@@ -4,7 +4,7 @@
<RootNamespace>Coscine.Database</RootNamespace>
<AssemblyName>Coscine.Database</AssemblyName>
<TargetFrameworks>net5.0;net461</TargetFrameworks>
<Version>2.0.1</Version>
<Version>2.1.0</Version>
</PropertyGroup>
<PropertyGroup>
<Authors>RWTH Aachen University</Authors>
......
using Coscine.Database.DataModel;
using Coscine.Database.ReturnObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace Coscine.Database.Models
{
// ------------------------------------------------------------------------------------
// This Class makes use of "GetAllWhere(...Id)" method rather than "GetById(...Id)"
// to make it future proof in case on a later stage more than a single entry
// is allowed inside the ContactChange table (e.g. history of contact change requests).
// To achieve that, remove usage of "DeleteAllDbEntries(...Id)" method.
// The line in quesiton is marked with an appropiate comment.
// ------------------------------------------------------------------------------------
public class ContactChangeModel : DatabaseModel<ContactChange>
{
public bool UserHasEmailsToConfirm(Guid userId)
{
// Perform deletion of all expired entries (older than 24 Hours).
DeleteExpiredDbEntries(userId);
IEnumerable<ContactChange> emailData = GetAllWhere((contactChange) => contactChange.UserId == userId);
// Return True if entries for a user exist inside the database table ContactChange. Else return False.
if (emailData.Count() > 0)
{
return true;
}
else
{
return false;
}
}
public ContactChangeObject NewEmailChangeRequest(Guid userId, string email)
{
if (UserHasEmailsToConfirm(userId))
{
DeleteAllDbEntries(userId); // <--- REMOVE THIS LINE IF YOU WANT TO KEEP HISTORY OF EMAIL CHANGES.
}
ContactChangeObject contactChangeObject = AddDbEntry(userId, email);
// Sending a confirmation email after an addition to the database is handled by the Controller.
return contactChangeObject;
}
public List<ContactChangeObject> GetEmailsForConfirmation(Guid userId)
{
List<ContactChangeObject> contactChangeObjects = new List<ContactChangeObject>();
IEnumerable<ContactChange> emailData = GetAllWhere((contactChange) => contactChange.UserId == userId);
foreach (var entry in emailData)
{
contactChangeObjects.Add(ToObject(entry));
}
return contactChangeObjects;
}
public UserObject ExecuteConfirmation(Guid token)
{
ContactChange emailData = GetWhere((contactChange) => contactChange.ConfirmationToken == token);
if (emailData != null)
{
if (emailData.EditDate != null)
{
// Add 23 Hours, 59 Minutes and 59 Seconds to EditDate, see when the token has to expire and compare with Now.
DateTime expirationDateTime = emailData.EditDate.Value.AddHours(23).AddMinutes(59).AddSeconds(59);
var compareDateTime = DateTime.Compare(expirationDateTime, DateTime.Now);
// Token EXPIRED when expirationDateTime = -1 (Expiration is BEFORE Now)
// Token VALID when expirationDateTime = 0 OR = 1 (Expiration IS Now or AFTER Now)
if (compareDateTime >= 0)
{
// VALID
UserModel userModel = new UserModel();
User user = userModel.GetById(emailData.UserId);
user.EmailAddress = emailData.NewEmail; // Overwrite old Email with New.
userModel.Update(user); // Update Database (User Table).
Delete(emailData); // Delete Entry from Database (ContactChange Table).
UserObject userObject = userModel.CreateReturnObjectFromDatabaseObject(userModel.GetWhere((usr) => usr.Id == emailData.UserId));
return userObject;
}
else
{
throw new Exception("EXPIRED: Token " + token.ToString() + " has expired.");
}
}
else
{
throw new ArgumentNullException("INVALID: Value EditDate is NULL for Token " + token.ToString() + ".");
}
}
else
{
throw new MissingFieldException("INVALID: The Token " + token.ToString() + " is not valid. No entry inside the Database.");
}
}
private void DeleteExpiredDbEntries(Guid userId)
{
IEnumerable<ContactChange> emailData = GetAllWhere((contactChange) => contactChange.UserId == userId);
foreach (var entry in emailData)
{
// Add 23 Hours, 59 Minutes and 59 Seconds to EditDate, see when the token has to expire and compare with Now.
DateTime expirationDateTime = entry.EditDate.Value.AddHours(23).AddMinutes(59).AddSeconds(59);
var compareDateTime = DateTime.Compare(expirationDateTime, DateTime.Now);
// Token EXPIRED when expirationDateTime = -1 (Expiration is BEFORE Now)
// Token VALID when expirationDateTime = 0 OR = 1 (Expiration IS Now or AFTER Now)
if (compareDateTime < 0)
{
Delete(entry);
}
}
}
private void DeleteAllDbEntries(Guid userId)
{
IEnumerable<ContactChange> emailData = GetAllWhere((contactChange) => contactChange.UserId == userId);
foreach (var entry in emailData)
{
Delete(entry);
}
}
private ContactChangeObject AddDbEntry(Guid userId, string email)
{
// Create new entry inside the Database for an Email Change Request for the specific User with an Id.
ContactChange contactChange = new ContactChange()
{
RelationId = Guid.NewGuid(),
UserId = userId,
NewEmail = email,
EditDate = DateTime.Now,
ConfirmationToken = Guid.NewGuid()
};
Insert(contactChange);
return ToObject(contactChange);
}
public static ContactChangeObject ToObject(ContactChange contactChange)
{
return new ContactChangeObject(
contactChange.RelationId,
contactChange.UserId,
contactChange.NewEmail,
contactChange.EditDate,
contactChange.ConfirmationToken
);
}
public static ContactChange FromObject(ContactChangeObject contactChangeObject)
{
return new ContactChange()
{
RelationId = contactChangeObject.RelationId,
UserId = contactChangeObject.UserId,
NewEmail = contactChangeObject.NewEmail,
EditDate = contactChangeObject.EditDate,
ConfirmationToken = contactChangeObject.ConfirmationToken
};
}
public override Expression<Func<ContactChange, Guid>> GetIdFromObject()
{
return (contactChange) => contactChange.RelationId;
}
public override Microsoft.EntityFrameworkCore.DbSet<ContactChange> GetITableFromDatabase(CoscineDB db)
{
return db.ContactChanges;
}
public override void SetObjectId(ContactChange databaseObject, Guid id)
{
databaseObject.RelationId = id;
}
}
}
using System;
namespace Coscine.Database.ReturnObjects
{
public class ContactChangeObject : IReturnObject
{
public Guid RelationId { get; set; }
public Guid UserId { get; set; }
public string NewEmail { get; set; }
public DateTime? EditDate { get; set; }
public Guid ConfirmationToken { get; set; }
public ContactChangeObject(Guid relationId, Guid userId, string newEmail, DateTime? editDate, Guid confirmationToken)
{
RelationId = relationId;
UserId = userId;
NewEmail = newEmail;
EditDate = editDate;
ConfirmationToken = confirmationToken;
}
}
}
......@@ -21,6 +21,7 @@ namespace Coscine.Database.DataModel
public virtual DbSet<ActivatedFeature> ActivatedFeatures { get; set; }
public virtual DbSet<ApiToken> ApiTokens { get; set; }
public virtual DbSet<ContactChange> ContactChanges { get; set; }
public virtual DbSet<Discipline> Disciplines { get; set; }
public virtual DbSet<ExternalAuthenticator> ExternalAuthenticators { get; set; }
public virtual DbSet<ExternalId> ExternalIds { get; set; }
......@@ -98,6 +99,29 @@ namespace Coscine.Database.DataModel
.HasConstraintName("FK_ApiTokens_UserId_Users_Id");
});
modelBuilder.Entity<ContactChange>(entity =>
{
entity.HasKey(e => e.RelationId);
entity.ToTable("ContactChange");
entity.Property(e => e.RelationId).HasDefaultValueSql("(newid())");
entity.Property(e => e.ConfirmationToken).HasDefaultValueSql("(newid())");
entity.Property(e => e.EditDate).HasColumnType("datetime");
entity.Property(e => e.NewEmail)
.IsRequired()
.HasMaxLength(200);
entity.HasOne(d => d.User)
.WithMany(p => p.ContactChanges)
.HasForeignKey(d => d.UserId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_ContactChange_UserId_Users_Id");
});
modelBuilder.Entity<Discipline>(entity =>
{
entity.Property(e => e.Id).HasDefaultValueSql("(newid())");
......
......@@ -12,6 +12,7 @@ namespace Coscine.Database.DataModel
public User()
{
ApiTokens = new HashSet<ApiToken>();
ContactChanges = new HashSet<ContactChange>();
ExternalIds = new HashSet<ExternalId>();
GroupMemberships = new HashSet<GroupMembership>();
ProjectRoles = new HashSet<ProjectRole>();
......@@ -33,6 +34,7 @@ namespace Coscine.Database.DataModel
public virtual Language Language { get; set; }
public virtual Title Title { get; set; }
public virtual ICollection<ApiToken> ApiTokens { get; set; }
public virtual ICollection<ContactChange> ContactChanges { get; set; }
public virtual ICollection<ExternalId> ExternalIds { get; set; }
public virtual ICollection<GroupMembership> GroupMemberships { get; set; }
public virtual ICollection<ProjectRole> ProjectRoles { get; set; }
......