+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.8.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.8.0-beta009")]
|
||||
[assembly: AssemblyFileVersion("7.9.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.9.0")]
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a consent.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class Consent : Entity, IConsent
|
||||
{
|
||||
private static PropertySelectors _selector;
|
||||
|
||||
private bool _current;
|
||||
private string _source;
|
||||
private string _context;
|
||||
private string _action;
|
||||
private ConsentState _state;
|
||||
private string _comment;
|
||||
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class PropertySelectors
|
||||
{
|
||||
public readonly PropertyInfo Current = ExpressionHelper.GetPropertyInfo<Consent, bool>(x => x.Current);
|
||||
public readonly PropertyInfo Source = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Source);
|
||||
public readonly PropertyInfo Context = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Context);
|
||||
public readonly PropertyInfo Action = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Action);
|
||||
public readonly PropertyInfo State = ExpressionHelper.GetPropertyInfo<Consent, ConsentState>(x => x.State);
|
||||
public readonly PropertyInfo Comment = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Comment);
|
||||
}
|
||||
|
||||
private static PropertySelectors Selectors => _selector ?? (_selector = new PropertySelectors());
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Current
|
||||
{
|
||||
get => _current;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _current, Selectors.Current);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Source
|
||||
{
|
||||
get => _source;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _source, Selectors.Source);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Context
|
||||
{
|
||||
get => _context;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _context, Selectors.Context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Action
|
||||
{
|
||||
get => _action;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _action, Selectors.Action);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConsentState State
|
||||
{
|
||||
get => _state;
|
||||
// note: we probably should validate the state here, but since the
|
||||
// enum is [Flags] with many combinations, this could be expensive
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _state, Selectors.State);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Comment
|
||||
{
|
||||
get => _comment;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _comment, Selectors.Comment);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IConsent> History => HistoryInternal;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous states of this consent.
|
||||
/// </summary>
|
||||
public List<IConsent> HistoryInternal { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for the <see cref="IConsent"/> interface.
|
||||
/// </summary>
|
||||
public static class ConsentExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the consent is granted.
|
||||
/// </summary>
|
||||
public static bool IsGranted(this IConsent consent) => (consent.State & ConsentState.Granted) > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the consent is revoked.
|
||||
/// </summary>
|
||||
public static bool IsRevoked(this IConsent consent) => (consent.State & ConsentState.Revoked) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state of a consent.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ConsentState // : int
|
||||
{
|
||||
// note - this is a [Flags] enumeration
|
||||
// on can create detailed flags such as:
|
||||
//GrantedOptIn = Granted | 0x0001
|
||||
//GrandedByForce = Granted | 0x0002
|
||||
//
|
||||
// 16 situations for each Pending/Granted/Revoked should be ok
|
||||
|
||||
/// <summary>
|
||||
/// There is no consent.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Consent is pending and has not been granted yet.
|
||||
/// </summary>
|
||||
Pending = 0x10000,
|
||||
|
||||
/// <summary>
|
||||
/// Consent has been granted.
|
||||
/// </summary>
|
||||
Granted = 0x20000,
|
||||
|
||||
/// <summary>
|
||||
/// Consent has been revoked.
|
||||
/// </summary>
|
||||
Revoked = 0x40000
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a consent state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A consent is fully identified by a source (whoever is consenting), a context (for
|
||||
/// example, an application), and an action (whatever is consented).</para>
|
||||
/// <para>A consent state registers the state of the consent (granted, revoked...).</para>
|
||||
/// </remarks>
|
||||
public interface IConsent : IAggregateRoot, IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the consent entity represents the current state.
|
||||
/// </summary>
|
||||
bool Current { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of whoever is consenting.
|
||||
/// </summary>
|
||||
string Source { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the context of the consent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Represents the domain, application, scope... of the action.</para>
|
||||
/// <para>When the action is a Udi, this should be the Udi type.</para>
|
||||
/// </remarks>
|
||||
string Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the consented action.
|
||||
/// </summary>
|
||||
string Action { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state of the consent.
|
||||
/// </summary>
|
||||
ConsentState State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets some additional free text.
|
||||
/// </summary>
|
||||
string Comment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous states of this consent.
|
||||
/// </summary>
|
||||
IEnumerable<IConsent> History { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName(TableName)]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
public class ConsentDto
|
||||
{
|
||||
internal const string TableName = "umbracoConsent";
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("current")]
|
||||
public bool Current { get; set; }
|
||||
|
||||
[Column("source")]
|
||||
[Length(512)]
|
||||
public string Source { get; set; }
|
||||
|
||||
[Column("context")]
|
||||
[Length(128)]
|
||||
public string Context { get; set; }
|
||||
|
||||
[Column("action")]
|
||||
[Length(512)]
|
||||
public string Action { get; set; }
|
||||
|
||||
[Column("createDate")]
|
||||
[Constraint(Default = SystemMethods.CurrentDateTime)]
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
[Column("state")]
|
||||
public int State { get; set; }
|
||||
|
||||
[Column("comment")]
|
||||
public string Comment { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal static class ConsentFactory
|
||||
{
|
||||
public static IEnumerable<IConsent> BuildEntities(IEnumerable<ConsentDto> dtos)
|
||||
{
|
||||
var ix = new Dictionary<string, Consent>();
|
||||
var output = new List<Consent>();
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var k = dto.Source + "::" + dto.Context + "::" + dto.Action;
|
||||
|
||||
var consent = new Consent
|
||||
{
|
||||
Id = dto.Id,
|
||||
Current = dto.Current,
|
||||
CreateDate = dto.CreateDate,
|
||||
Source = dto.Source,
|
||||
Context = dto.Context,
|
||||
Action = dto.Action,
|
||||
State = (ConsentState) dto.State, // assume value is valid
|
||||
Comment = dto.Comment
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
consent.ResetDirtyProperties(false);
|
||||
|
||||
if (ix.TryGetValue(k, out var current))
|
||||
{
|
||||
if (current.HistoryInternal == null)
|
||||
current.HistoryInternal = new List<IConsent>();
|
||||
current.HistoryInternal.Add(consent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ix[k] = consent;
|
||||
output.Add(consent);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static ConsentDto BuildDto(IConsent entity)
|
||||
{
|
||||
return new ConsentDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
Current = entity.Current,
|
||||
CreateDate = entity.CreateDate,
|
||||
Source = entity.Source,
|
||||
Context = entity.Context,
|
||||
Action = entity.Action,
|
||||
State = (int) entity.State,
|
||||
Comment = entity.Comment
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mapper for consent entities.
|
||||
/// </summary>
|
||||
[MapperFor(typeof(IConsent))]
|
||||
[MapperFor(typeof(Consent))]
|
||||
public sealed class ConsentMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance
|
||||
= new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConsentMapper"/> class.
|
||||
/// </summary>
|
||||
public ConsentMapper()
|
||||
{
|
||||
// note: why the base ctor does not invoke BuildMap is a mystery to me
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Id, dto => dto.Id);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Current, dto => dto.Current);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Source, dto => dto.Source);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Context, dto => dto.Context);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Action, dto => dto.Action);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.State, dto => dto.State);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Comment, dto => dto.Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
{52, typeof (UserGroup2NodePermissionDto) },
|
||||
{53, typeof (UserGroup2AppDto) },
|
||||
{54, typeof (UserStartNodeDto) },
|
||||
{55, typeof (UserLoginDto)}
|
||||
{55, typeof (UserLoginDto)},
|
||||
{56, typeof (ConsentDto)}
|
||||
};
|
||||
#endregion
|
||||
|
||||
@@ -378,4 +379,4 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenNineZero
|
||||
{
|
||||
[Migration("7.9.0", 1, Constants.System.UmbracoMigrationName)]
|
||||
public class AddUmbracoConsentTable : MigrationBase
|
||||
{
|
||||
public AddUmbracoConsentTable(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(ConsentDto.TableName))
|
||||
return;
|
||||
|
||||
Create.Table<ConsentDto>();
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the PetaPoco implementation of <see cref="IConsentRepository"/>.
|
||||
/// </summary>
|
||||
internal class ConsentRepository : PetaPocoRepositoryBase<int, IConsent>, IConsentRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConsentRepository"/> class.
|
||||
/// </summary>
|
||||
public ConsentRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
|
||||
: base(work, cache, logger, sqlSyntax)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Guid NodeObjectTypeId => throw new NotSupportedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearCurrent(string source, string context, string action)
|
||||
{
|
||||
var sql = new Sql($@"UPDATE {SqlSyntax.GetQuotedTableName(ConsentDto.TableName)}
|
||||
SET {SqlSyntax.GetQuotedColumnName("current")} = @0
|
||||
WHERE {SqlSyntax.GetQuotedColumnName("source")} = @1 AND {SqlSyntax.GetQuotedColumnName("context")} = @2 AND {SqlSyntax.GetQuotedColumnName("action")} = @3
|
||||
AND {SqlSyntax.GetQuotedColumnName("current")} <> @0 ", false, source, context, action);
|
||||
|
||||
Database.Execute(sql);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IConsent PerformGet(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<IConsent> PerformGetAll(params int[] ids)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<IConsent> PerformGetByQuery(IQuery<IConsent> query)
|
||||
{
|
||||
var sqlClause = new Sql().Select("*").From<ConsentDto>(SqlSyntax);
|
||||
var translator = new SqlTranslator<IConsent>(sqlClause, query);
|
||||
var sql = translator.Translate().OrderByDescending<ConsentDto>(x => x.CreateDate, SqlSyntax);
|
||||
return ConsentFactory.BuildEntities(Database.Fetch<ConsentDto>(sql));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void PersistNewItem(IConsent entity)
|
||||
{
|
||||
((Entity) entity).AddingEntity();
|
||||
|
||||
var dto = ConsentFactory.BuildDto(entity);
|
||||
Database.Insert(dto);
|
||||
entity.Id = dto.Id;
|
||||
entity.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void PersistUpdatedItem(IConsent entity)
|
||||
{
|
||||
((Entity) entity).UpdatingEntity();
|
||||
|
||||
var dto = ConsentFactory.BuildDto(entity);
|
||||
Database.Update(dto);
|
||||
entity.ResetDirtyProperties();
|
||||
|
||||
IsolatedCache.ClearCacheItem(GetCacheIdKey<IConsent>(entity.Id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a repository for <see cref="IConsent"/> entities.
|
||||
/// </summary>
|
||||
public interface IConsentRepository : IRepositoryQueryable<int, IConsent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Clears the current flag.
|
||||
/// </summary>
|
||||
void ClearCurrent(string source, string context, string action);
|
||||
}
|
||||
}
|
||||
@@ -397,5 +397,10 @@ namespace Umbraco.Core.Persistence
|
||||
_logger,
|
||||
_sqlSyntax);
|
||||
}
|
||||
|
||||
public IConsentRepository CreateConsentRepository(IScopeUnitOfWork uow)
|
||||
{
|
||||
return new ConsentRepository(uow, _cacheHelper, _logger, _sqlSyntax);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements <see cref="IContentService"/>.
|
||||
/// </summary>
|
||||
internal class ConsentService : ScopeRepositoryService, IConsentService
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentService"/> class.
|
||||
/// </summary>
|
||||
public ConsentService(IScopeUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
{ }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IConsent Register(string source, string context, string action, ConsentState state, string comment = null)
|
||||
{
|
||||
// prevent stupid states
|
||||
var v = 0;
|
||||
if ((state & ConsentState.Pending) > 0) v++;
|
||||
if ((state & ConsentState.Granted) > 0) v++;
|
||||
if ((state & ConsentState.Revoked) > 0) v++;
|
||||
if (v != 1)
|
||||
throw new ArgumentException("Invalid state.", nameof(state));
|
||||
|
||||
var consent = new Consent
|
||||
{
|
||||
Current = true,
|
||||
Source = source,
|
||||
Context = context,
|
||||
Action = action,
|
||||
CreateDate = DateTime.Now,
|
||||
State = state,
|
||||
Comment = comment
|
||||
};
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
var repository = RepositoryFactory.CreateConsentRepository(uow);
|
||||
repository.ClearCurrent(source, context, action);
|
||||
repository.AddOrUpdate(consent);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
return consent;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IConsent> Get(string source = null, string context = null, string action = null,
|
||||
bool sourceStartsWith = false, bool contextStartsWith = false, bool actionStartsWith = false,
|
||||
bool includeHistory = false)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateConsentRepository(uow);
|
||||
|
||||
IQuery<IConsent> query = new Query<IConsent>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(source) == false)
|
||||
query = sourceStartsWith ? query.Where(x => x.Source.StartsWith(source)) : query.Where(x => x.Source == source);
|
||||
if (string.IsNullOrWhiteSpace(context) == false)
|
||||
query = contextStartsWith ? query.Where(x => x.Context.StartsWith(context)) : query.Where(x => x.Context == context);
|
||||
if (string.IsNullOrWhiteSpace(action) == false)
|
||||
query = actionStartsWith ? query.Where(x => x.Action.StartsWith(action)) : query.Where(x => x.Action == action);
|
||||
if (includeHistory == false)
|
||||
query = query.Where(x => x.Current);
|
||||
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a service for handling <see cref="IConsent"/> entities.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Consent can be given or revoked or changed via the <see cref="Register"/> method, which
|
||||
/// creates a new <see cref="IConsent"/> entity to track the consent. Revoking a consent is performed by
|
||||
/// registering a revoked consent.</para>
|
||||
/// <para>A consent can be revoked, by registering a revoked consent, but cannot be deleted.</para>
|
||||
/// <para>Getter methods return the current state of a consent, i.e. the latest <see cref="IConsent"/>
|
||||
/// entity that was created.</para>
|
||||
/// </remarks>
|
||||
public interface IConsentService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers consent.
|
||||
/// </summary>
|
||||
/// <param name="source">The source, i.e. whoever is consenting.</param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="state">The state of the consent.</param>
|
||||
/// <param name="comment">Additional free text.</param>
|
||||
/// <returns>The corresponding consent entity.</returns>
|
||||
IConsent Register(string source, string context, string action, ConsentState state, string comment = null);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves consents.
|
||||
/// </summary>
|
||||
/// <param name="source">The optional source.</param>
|
||||
/// <param name="context">The optional context.</param>
|
||||
/// <param name="action">The optional action.</param>
|
||||
/// <param name="sourceStartsWith">Determines whether <paramref name="source"/> is a start pattern.</param>
|
||||
/// <param name="contextStartsWith">Determines whether <paramref name="context"/> is a start pattern.</param>
|
||||
/// <param name="actionStartsWith">Determines whether <paramref name="action"/> is a start pattern.</param>
|
||||
/// <param name="includeHistory">Determines whether to include the history of consents.</param>
|
||||
/// <returns>Consents matching the paramters.</returns>
|
||||
IEnumerable<IConsent> Get(string source = null, string context = null, string action = null,
|
||||
bool sourceStartsWith = false, bool contextStartsWith = false, bool actionStartsWith = false,
|
||||
bool includeHistory = false);
|
||||
}
|
||||
}
|
||||
@@ -62,38 +62,13 @@ namespace Umbraco.Core.Services
|
||||
private Lazy<INotificationService> _notificationService;
|
||||
private Lazy<IExternalLoginService> _externalLoginService;
|
||||
private Lazy<IRedirectUrlService> _redirectUrlService;
|
||||
private Lazy<IConsentService> _consentService;
|
||||
|
||||
internal IdkMap IdkMap { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// public ctor - will generally just be used for unit testing all items are optional and if not specified, the defaults will be used
|
||||
/// </summary>
|
||||
/// <param name="contentService"></param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <param name="contentTypeService"></param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
/// <param name="fileService"></param>
|
||||
/// <param name="localizationService"></param>
|
||||
/// <param name="packagingService"></param>
|
||||
/// <param name="entityService"></param>
|
||||
/// <param name="relationService"></param>
|
||||
/// <param name="memberGroupService"></param>
|
||||
/// <param name="memberTypeService"></param>
|
||||
/// <param name="memberService"></param>
|
||||
/// <param name="userService"></param>
|
||||
/// <param name="sectionService"></param>
|
||||
/// <param name="treeService"></param>
|
||||
/// <param name="tagService"></param>
|
||||
/// <param name="notificationService"></param>
|
||||
/// <param name="localizedTextService"></param>
|
||||
/// <param name="auditService"></param>
|
||||
/// <param name="domainService"></param>
|
||||
/// <param name="taskService"></param>
|
||||
/// <param name="macroService"></param>
|
||||
/// <param name="publicAccessService"></param>
|
||||
/// <param name="externalLoginService"></param>
|
||||
/// <param name="migrationEntryService"></param>
|
||||
/// <param name="redirectUrlService"></param>
|
||||
public ServiceContext(
|
||||
IContentService contentService = null,
|
||||
IMediaService mediaService = null,
|
||||
@@ -120,7 +95,8 @@ namespace Umbraco.Core.Services
|
||||
IPublicAccessService publicAccessService = null,
|
||||
IExternalLoginService externalLoginService = null,
|
||||
IMigrationEntryService migrationEntryService = null,
|
||||
IRedirectUrlService redirectUrlService = null)
|
||||
IRedirectUrlService redirectUrlService = null,
|
||||
IConsentService consentService = null)
|
||||
{
|
||||
if (migrationEntryService != null) _migrationEntryService = new Lazy<IMigrationEntryService>(() => migrationEntryService);
|
||||
if (externalLoginService != null) _externalLoginService = new Lazy<IExternalLoginService>(() => externalLoginService);
|
||||
@@ -148,6 +124,7 @@ namespace Umbraco.Core.Services
|
||||
if (macroService != null) _macroService = new Lazy<IMacroService>(() => macroService);
|
||||
if (publicAccessService != null) _publicAccessService = new Lazy<IPublicAccessService>(() => publicAccessService);
|
||||
if (redirectUrlService != null) _redirectUrlService = new Lazy<IRedirectUrlService>(() => redirectUrlService);
|
||||
if (consentService != null) _consentService = new Lazy<IConsentService>(() => consentService);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -310,6 +287,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
if (_redirectUrlService == null)
|
||||
_redirectUrlService = new Lazy<IRedirectUrlService>(() => new RedirectUrlService(provider, repositoryFactory, logger, eventMessagesFactory));
|
||||
|
||||
if (_consentService == null)
|
||||
_consentService = new Lazy<IConsentService>(() => new ConsentService(provider, repositoryFactory, logger, eventMessagesFactory));
|
||||
}
|
||||
|
||||
internal IEventMessagesFactory EventMessagesFactory { get; private set; }
|
||||
@@ -526,5 +506,10 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
get { return _redirectUrlService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IConsentService"/> implementation.
|
||||
/// </summary>
|
||||
public IConsentService ConsentService => _consentService.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -363,9 +364,13 @@
|
||||
<Compile Include="IEmailSender.cs" />
|
||||
<Compile Include="IHttpContextAccessor.cs" />
|
||||
<Compile Include="Logging\RollingFileCleanupAppender.cs" />
|
||||
<Compile Include="Models\Consent.cs" />
|
||||
<Compile Include="Models\ConsentExtensions.cs" />
|
||||
<Compile Include="Models\ConsentState.cs" />
|
||||
<Compile Include="Models\EntityBase\EntityPath.cs" />
|
||||
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
|
||||
<Compile Include="Models\IAuditItem.cs" />
|
||||
<Compile Include="Models\IConsent.cs" />
|
||||
<Compile Include="Models\IUserControl.cs" />
|
||||
<Compile Include="Models\Membership\ContentPermissionSet.cs" />
|
||||
<Compile Include="Models\Membership\EntityPermissionCollection.cs" />
|
||||
@@ -377,6 +382,7 @@
|
||||
<Compile Include="Models\Membership\UserState.cs" />
|
||||
<Compile Include="Models\Membership\UserType.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
|
||||
<Compile Include="Models\Rdbms\ConsentDto.cs" />
|
||||
<Compile Include="Models\Rdbms\MediaDto.cs" />
|
||||
<Compile Include="Models\Rdbms\UserLoginDto.cs" />
|
||||
<Compile Include="Models\Rdbms\UserStartNodeDto.cs" />
|
||||
@@ -541,6 +547,7 @@
|
||||
<Compile Include="Persistence\LockingRepository.cs" />
|
||||
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\AuditMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ConsentMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ExternalLoginMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
|
||||
@@ -552,6 +559,7 @@
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddInstructionCountColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddCmsMediaTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenEightZero\AddUserLoginTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenNineZero\AddUmbracoConsentTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenNineZero\AddIsSensitiveMemberTypeColumn.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenNineZero\CreateSensitiveDataUserGroup.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSevenZero\AddIndexToDictionaryKeyColumn.cs" />
|
||||
@@ -626,10 +634,13 @@
|
||||
<Compile Include="Persistence\Relators\UserGroupSectionRelator.cs" />
|
||||
<Compile Include="Persistence\Repositories\AuditRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\BaseQueryType.cs" />
|
||||
<Compile Include="Persistence\Factories\ConsentFactory.cs" />
|
||||
<Compile Include="Persistence\Repositories\ConsentRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\ContentBlueprintRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\EntityContainerRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\DomainRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\ExternalLoginRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\IConsentRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IAuditRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IContentTypeCompositionRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IDomainRepository.cs" />
|
||||
@@ -726,8 +737,10 @@
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\CreateCacheInstructionTable.cs" />
|
||||
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\MigrateStylesheetDataToFile.cs" />
|
||||
<Compile Include="Services\AuditService.cs" />
|
||||
<Compile Include="Services\ConsentService.cs" />
|
||||
<Compile Include="Services\ContentTypeServiceExtensions.cs" />
|
||||
<Compile Include="Models\RedirectUrl.cs" />
|
||||
<Compile Include="Services\IConsentService.cs" />
|
||||
<Compile Include="Services\IContentServiceBase.cs" />
|
||||
<Compile Include="Services\IdkMap.cs" />
|
||||
<Compile Include="Services\MediaServiceExtensions.cs" />
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String></wpf:ResourceDictionary>
|
||||
@@ -271,7 +271,7 @@ AnotherContentFinder
|
||||
public void Resolves_Assigned_Mappers()
|
||||
{
|
||||
var foundTypes1 = _manager.ResolveAssignedMapperTypes();
|
||||
Assert.AreEqual(29, foundTypes1.Count());
|
||||
Assert.AreEqual(30, foundTypes1.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -390,4 +390,4 @@ AnotherContentFinder
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
[TestFixture]
|
||||
public class ImageCropperTest
|
||||
{
|
||||
private const string cropperJson1 = "{\"focalPoint\": {\"left\": 0.96,\"top\": 0.80827067669172936},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\":\"thumb\",\"width\": 100,\"height\": 100,\"coordinates\": {\"x1\": 0.58729977382575338,\"y1\": 0.055768992440203169,\"x2\": 0,\"y2\": 0.32457553600198386}}]}";
|
||||
private const string cropperJson1 = "{\"focalPoint\": {\"left\": 0.96,\"top\": 0.80827067669172936},\"src\": \"/media/1005/img_0671.jpg\",\"crops\": [{\"alias\":\"thumb\",\"width\": 100,\"height\": 100,\"coordinates\": {\"x1\": 0.58729977382575338,\"y1\": 0.055768992440203169,\"x2\": 0,\"y2\": 0.32457553600198386}}]}";
|
||||
private const string cropperJson2 = "{\"focalPoint\": {\"left\": 0.98,\"top\": 0.80827067669172936},\"src\": \"/media/1005/img_0672.jpg\",\"crops\": [{\"alias\":\"thumb\",\"width\": 100,\"height\": 100,\"coordinates\": {\"x1\": 0.58729977382575338,\"y1\": 0.055768992440203169,\"x2\": 0,\"y2\": 0.32457553600198386}}]}";
|
||||
private const string cropperJson3 = "{\"focalPoint\": {\"left\": 0.98,\"top\": 0.80827067669172936},\"src\": \"/media/1005/img_0672.jpg\",\"crops\": []}";
|
||||
private const string mediaPath = "/media/1005/img_0671.jpg";
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
index++;
|
||||
}
|
||||
|
||||
Assert.AreEqual(index, 1);
|
||||
Assert.AreEqual(index, 1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -136,7 +136,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
}
|
||||
|
||||
[TestCase(cropperJson1, cropperJson1, true)]
|
||||
[TestCase(cropperJson1, cropperJson2, false)]
|
||||
[TestCase(cropperJson1, cropperJson2, false)]
|
||||
public void CanConvertImageCropperPropertyEditor(string val1, string val2, bool expected)
|
||||
{
|
||||
try
|
||||
@@ -266,7 +266,7 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
var urlStringPad = mediaPath.GetCropUrl(imageCropperValue: cropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Pad);
|
||||
var urlStringMax = mediaPath.GetCropUrl(imageCropperValue: cropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Max);
|
||||
var urlStringStretch = mediaPath.GetCropUrl(imageCropperValue: cropperJson1, width: 300, height: 150, imageCropMode: ImageCropMode.Stretch);
|
||||
|
||||
|
||||
Assert.AreEqual(mediaPath + "?mode=min&width=300&height=150", urlStringMin);
|
||||
Assert.AreEqual(mediaPath + "?mode=boxpad&width=300&height=150", urlStringBoxPad);
|
||||
Assert.AreEqual(mediaPath + "?mode=pad&width=300&height=150", urlStringPad);
|
||||
@@ -380,4 +380,4 @@ namespace Umbraco.Tests.PropertyEditors
|
||||
Assert.AreEqual(mediaPath + "?mode=pad&width=400&height=400&bgcolor=fff", urlString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerFixture)]
|
||||
public class ConsentServiceTests : BaseServiceTest
|
||||
{
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanCrudConsent()
|
||||
{
|
||||
// fixme - why isn't this set by the test base class?
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
|
||||
var consentService = ServiceContext.ConsentService;
|
||||
|
||||
// can register
|
||||
|
||||
var consent = consentService.Register("user/1234", "app1", "do-something", ConsentState.Granted, "no comment");
|
||||
Assert.AreNotEqual(0, consent.Id);
|
||||
|
||||
Assert.IsTrue(consent.Current);
|
||||
Assert.AreEqual("user/1234", consent.Source);
|
||||
Assert.AreEqual("app1", consent.Context);
|
||||
Assert.AreEqual("do-something", consent.Action);
|
||||
Assert.AreEqual(ConsentState.Granted, consent.State);
|
||||
Assert.AreEqual("no comment", consent.Comment);
|
||||
|
||||
Assert.IsTrue(consent.IsGranted());
|
||||
|
||||
// can register more
|
||||
|
||||
consentService.Register("user/1234", "app1", "do-something-else", ConsentState.Granted, "no comment");
|
||||
consentService.Register("user/1236", "app1", "do-something", ConsentState.Granted, "no comment");
|
||||
consentService.Register("user/1237", "app2", "do-something", ConsentState.Granted, "no comment");
|
||||
|
||||
// can get by source
|
||||
|
||||
var consents = consentService.Get(source: "user/1235").ToArray();
|
||||
Assert.IsEmpty(consents);
|
||||
|
||||
consents = consentService.Get(source: "user/1234").ToArray();
|
||||
Assert.AreEqual(2, consents.Length);
|
||||
Assert.IsTrue(consents.All(x => x.Source == "user/1234"));
|
||||
Assert.IsTrue(consents.Any(x => x.Action == "do-something"));
|
||||
Assert.IsTrue(consents.Any(x => x.Action == "do-something-else"));
|
||||
|
||||
// can get by context
|
||||
|
||||
consents = consentService.Get(context: "app3").ToArray();
|
||||
Assert.IsEmpty(consents);
|
||||
|
||||
consents = consentService.Get(context: "app2").ToArray();
|
||||
Assert.AreEqual(1, consents.Length);
|
||||
|
||||
consents = consentService.Get(context: "app1").ToArray();
|
||||
Assert.AreEqual(3, consents.Length);
|
||||
Assert.IsTrue(consents.Any(x => x.Action == "do-something"));
|
||||
Assert.IsTrue(consents.Any(x => x.Action == "do-something-else"));
|
||||
|
||||
// can get by action
|
||||
|
||||
consents = consentService.Get(action: "do-whatever").ToArray();
|
||||
Assert.IsEmpty(consents);
|
||||
|
||||
consents = consentService.Get(context: "app1", action: "do-something").ToArray();
|
||||
Assert.AreEqual(2, consents.Length);
|
||||
Assert.IsTrue(consents.All(x => x.Action == "do-something"));
|
||||
Assert.IsTrue(consents.Any(x => x.Source == "user/1234"));
|
||||
Assert.IsTrue(consents.Any(x => x.Source == "user/1236"));
|
||||
|
||||
// can revoke
|
||||
|
||||
consent = consentService.Register("user/1234", "app1", "do-something", ConsentState.Revoked, "no comment");
|
||||
|
||||
consents = consentService.Get(source: "user/1234", context: "app1", action: "do-something").ToArray();
|
||||
Assert.AreEqual(1, consents.Length);
|
||||
Assert.IsTrue(consents[0].Current);
|
||||
Assert.AreEqual(ConsentState.Revoked, consents[0].State);
|
||||
|
||||
// can filter
|
||||
|
||||
consents = consentService.Get(context: "app1", action: "do-", actionStartsWith: true).ToArray();
|
||||
Assert.AreEqual(3, consents.Length);
|
||||
Assert.IsTrue(consents.All(x => x.Context == "app1"));
|
||||
Assert.IsTrue(consents.All(x => x.Action.StartsWith("do-")));
|
||||
|
||||
// can get history
|
||||
|
||||
consents = consentService.Get(source: "user/1234", context: "app1", action: "do-something", includeHistory: true).ToArray();
|
||||
Assert.AreEqual(1, consents.Length);
|
||||
Assert.IsTrue(consents[0].Current);
|
||||
Assert.AreEqual(ConsentState.Revoked, consents[0].State);
|
||||
Assert.IsTrue(consents[0].IsRevoked());
|
||||
Assert.IsNotNull(consents[0].History);
|
||||
var history = consents[0].History.ToArray();
|
||||
Assert.AreEqual(1, history.Length);
|
||||
Assert.IsFalse(history[0].Current);
|
||||
Assert.AreEqual(ConsentState.Granted, history[0].State);
|
||||
|
||||
// cannot be stupid
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
consentService.Register("user/1234", "app1", "do-something", ConsentState.Granted | ConsentState.Revoked, "no comment"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,6 +190,7 @@
|
||||
<Compile Include="Models\Mapping\UserModelMapperTests.cs" />
|
||||
<Compile Include="Packaging\PackageExtractionTests.cs" />
|
||||
<Compile Include="Persistence\Repositories\SimilarNodeNameTests.cs" />
|
||||
<Compile Include="Services\ConsentServiceTests.cs" />
|
||||
<Compile Include="TestHelpers\ControllerTesting\AuthenticateEverythingExtensions.cs" />
|
||||
<Compile Include="TestHelpers\ControllerTesting\AuthenticateEverythingMiddleware.cs" />
|
||||
<Compile Include="TestHelpers\ControllerTesting\SpecificAssemblyResolver.cs" />
|
||||
|
||||
@@ -1024,8 +1024,10 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>7800</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>7900</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:7900</IISUrl>
|
||||
<DevelopmentServerPort>7790</DevelopmentServerPort>
|
||||
<IISUrl>http://localhost:7800</IISUrl>
|
||||
<DevelopmentServerPort>7800</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=2DA32DA040A7D74599ABE288C7224CF0/Comment/@EntryValue">Disposable construction</s:String>
|
||||
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=2DA32DA040A7D74599ABE288C7224CF0/Severity/@EntryValue">HINT</s:String>
|
||||
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=37A0B37A0ABAA34AA5CB32A93653C4FE/@KeyIndexDefined">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp72</s:String></wpf:ResourceDictionary>
|
||||
</wpf:ResourceDictionary>
|
||||
Reference in New Issue
Block a user