Added NLog, Added UserService, Added database and seed seed
This commit is contained in:
		@@ -5,6 +5,7 @@
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\Birdmap.Common\Birdmap.Common.csproj" />
 | 
			
		||||
    <ProjectReference Include="..\Birdmap.DAL\Birdmap.DAL.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,26 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.BLL.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    public class AuthenticationException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public AuthenticationException()
 | 
			
		||||
            : base("Username or password is incorrect.")
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationException(string message) : this()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AuthenticationException(string message, Exception innerException) : this()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected AuthenticationException(SerializationInfo info, StreamingContext context) : base(info, context)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								Birdmap.BLL/Exceptions/EntityNotFoundException.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Birdmap.BLL/Exceptions/EntityNotFoundException.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Runtime.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.BLL.Exceptions
 | 
			
		||||
{
 | 
			
		||||
    [Serializable]
 | 
			
		||||
    public class EntityNotFoundException : Exception
 | 
			
		||||
    {
 | 
			
		||||
        public EntityNotFoundException()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public EntityNotFoundException(string message) : base(message)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public EntityNotFoundException(string message, Exception innerException) : base(message, innerException)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected EntityNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,5 +6,6 @@ namespace Birdmap.BLL.Interfaces
 | 
			
		||||
    public interface IAuthService
 | 
			
		||||
    {
 | 
			
		||||
        Task<User> AuthenticateUserAsync(string username, string password);
 | 
			
		||||
        Task<User> RegisterUserAsync(string username, string password);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								Birdmap.BLL/Interfaces/IUserService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Birdmap.BLL/Interfaces/IUserService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
using Birdmap.DAL.Entities;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.BLL.Interfaces
 | 
			
		||||
{
 | 
			
		||||
    public interface IUserService
 | 
			
		||||
    {
 | 
			
		||||
        Task<User> GetUserAsync(int userId);
 | 
			
		||||
        Task<User> GetUserAsync(string username);
 | 
			
		||||
        Task<User> CreateUserAsync(User user);
 | 
			
		||||
        Task UpdateUserAsync(User user);
 | 
			
		||||
        Task DeleteUserAsync(int userId);
 | 
			
		||||
        Task DeleteUserAsync(string username);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +1,19 @@
 | 
			
		||||
using Birdmap.DAL.Entities;
 | 
			
		||||
using Birdmap.BLL.Interfaces;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Birdmap.BLL.Interfaces;
 | 
			
		||||
using Birdmap.DAL.Entities;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Security.Authentication;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Birdmap.DAL;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using static Birdmap.Common.PasswordHelper;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.BLL.Services
 | 
			
		||||
{
 | 
			
		||||
    public class AuthService : IAuthService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly BirdmapContext _context;
 | 
			
		||||
        private readonly IUserService _userService;
 | 
			
		||||
 | 
			
		||||
        public AuthService(BirdmapContext context)
 | 
			
		||||
        public AuthService(IUserService userService)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
            _userService = userService;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<User> AuthenticateUserAsync(string username, string password)
 | 
			
		||||
@@ -29,9 +24,17 @@ namespace Birdmap.BLL.Services
 | 
			
		||||
            return AuthenticateUserInternalAsync(username, password);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task<User> RegisterUserAsync(string username, string password)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(username) || string.IsNullOrEmpty(password))
 | 
			
		||||
                throw new ArgumentException("Username or password cannot be null or empty.");
 | 
			
		||||
 | 
			
		||||
            return RegisterUserInternalAsync(username, password);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<User> AuthenticateUserInternalAsync(string username, string password)
 | 
			
		||||
        {
 | 
			
		||||
            var user = await _context.Users.SingleOrDefaultAsync(u => u.Name == username)
 | 
			
		||||
            var user = await _userService.GetUserAsync(username)
 | 
			
		||||
                ?? throw new AuthenticationException();
 | 
			
		||||
 | 
			
		||||
            if (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))
 | 
			
		||||
@@ -40,45 +43,18 @@ namespace Birdmap.BLL.Services
 | 
			
		||||
            return user;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task<User> Temp_GetUserAsync(IConfiguration configuration)
 | 
			
		||||
        private Task<User> RegisterUserInternalAsync(string username, string password)
 | 
			
		||||
        {
 | 
			
		||||
            var name = configuration["BasicAuth:Username"];
 | 
			
		||||
            var pass = configuration["BasicAuth:Password"];
 | 
			
		||||
 | 
			
		||||
            CreatePasswordHash(pass, out var hash, out var salt);
 | 
			
		||||
            return Task.FromResult(new User
 | 
			
		||||
            CreatePasswordHash(password, out var hash, out var salt);
 | 
			
		||||
            var user = new User
 | 
			
		||||
            {
 | 
			
		||||
                Name = name,
 | 
			
		||||
                Name = username,
 | 
			
		||||
                PasswordHash = hash,
 | 
			
		||||
                PasswordSalt = salt,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
                Role = Roles.User,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        private static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
 | 
			
		||||
 | 
			
		||||
            using var hmac = new System.Security.Cryptography.HMACSHA512();
 | 
			
		||||
 | 
			
		||||
            passwordSalt = hmac.Key;
 | 
			
		||||
            passwordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be null or empty.", nameof(password));
 | 
			
		||||
            if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", nameof(storedHash));
 | 
			
		||||
            if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", nameof(storedSalt));
 | 
			
		||||
 | 
			
		||||
            using var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt);
 | 
			
		||||
 | 
			
		||||
            var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
 | 
			
		||||
            for (int i = 0; i < computedHash.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (computedHash[i] != storedHash[i]) return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
            return _userService.CreateUserAsync(user);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								Birdmap.BLL/Services/UserService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Birdmap.BLL/Services/UserService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
using Birdmap.BLL.Exceptions;
 | 
			
		||||
using Birdmap.BLL.Interfaces;
 | 
			
		||||
using Birdmap.DAL;
 | 
			
		||||
using Birdmap.DAL.Entities;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.BLL.Services
 | 
			
		||||
{
 | 
			
		||||
    public class UserService : IUserService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly BirdmapContext _context;
 | 
			
		||||
 | 
			
		||||
        public UserService(BirdmapContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<User> CreateUserAsync(User user)
 | 
			
		||||
        {
 | 
			
		||||
            _context.Users.Add(user);
 | 
			
		||||
            await _context.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
            return user;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task DeleteUserAsync(int userId)
 | 
			
		||||
        {
 | 
			
		||||
            return DeleteUserInternalAsync(userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task DeleteUserAsync(string username)
 | 
			
		||||
        {
 | 
			
		||||
            return DeleteUserInternalAsync(username);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<User> GetUserAsync(int userId)
 | 
			
		||||
        {
 | 
			
		||||
            return await _context.Users.SingleOrDefaultAsync(u => u.Id == userId)
 | 
			
		||||
                ?? throw new EntityNotFoundException($"Cannot find user with user ID: {userId}");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<User> GetUserAsync(string username)
 | 
			
		||||
        {
 | 
			
		||||
            return await _context.Users.SingleOrDefaultAsync(u => u.Name == username)
 | 
			
		||||
                ?? throw new EntityNotFoundException($"Cannot find user with username: {username}");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Task UpdateUserAsync(User user)
 | 
			
		||||
        {
 | 
			
		||||
            _context.Users.Update(user);
 | 
			
		||||
            return _context.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task DeleteUserInternalAsync(object key)
 | 
			
		||||
        {
 | 
			
		||||
            var user = _context.Users.Find(key);
 | 
			
		||||
 | 
			
		||||
            if (user == null)
 | 
			
		||||
                return Task.CompletedTask;
 | 
			
		||||
 | 
			
		||||
            _context.Users.Remove(user);
 | 
			
		||||
            return _context.SaveChangesAsync();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -10,6 +10,7 @@ namespace Birdmap.BLL
 | 
			
		||||
        public static IServiceCollection ConfigureBLL(this IServiceCollection services, IConfiguration configuration)
 | 
			
		||||
        {
 | 
			
		||||
            services.AddTransient<IAuthService, AuthService>();
 | 
			
		||||
            services.AddTransient<IUserService, UserService>();
 | 
			
		||||
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								Birdmap.Common/Birdmap.Common.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Birdmap.Common/Birdmap.Common.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netcoreapp3.1</TargetFramework>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										35
									
								
								Birdmap.Common/PasswordHelper.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Birdmap.Common/PasswordHelper.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.Common
 | 
			
		||||
{
 | 
			
		||||
    public static class PasswordHelper
 | 
			
		||||
    {
 | 
			
		||||
        public static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
 | 
			
		||||
 | 
			
		||||
            using var hmac = new System.Security.Cryptography.HMACSHA512();
 | 
			
		||||
 | 
			
		||||
            passwordSalt = hmac.Key;
 | 
			
		||||
            passwordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be null or empty.", nameof(password));
 | 
			
		||||
            if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", nameof(storedHash));
 | 
			
		||||
            if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", nameof(storedSalt));
 | 
			
		||||
 | 
			
		||||
            using var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt);
 | 
			
		||||
 | 
			
		||||
            var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
 | 
			
		||||
            for (int i = 0; i < computedHash.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (computedHash[i] != storedHash[i]) return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,15 @@
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.9" />
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.9" />
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.9">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="3.1.9" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\Birdmap.Common\Birdmap.Common.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,20 +8,13 @@ namespace Birdmap.DAL
 | 
			
		||||
    {
 | 
			
		||||
        public DbSet<User> Users { get; set; }
 | 
			
		||||
 | 
			
		||||
        public BirdmapContext([NotNull] DbContextOptions options) : base(options)
 | 
			
		||||
        public BirdmapContext([NotNull] DbContextOptions<BirdmapContext> options) : base(options)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            modelBuilder.ApplyConfigurationsFromAssembly(typeof(BirdmapContext).Assembly);
 | 
			
		||||
 | 
			
		||||
            SeedDatabase(modelBuilder);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SeedDatabase(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								Birdmap.DAL/Entities/Configurations/ServiceConfiguration.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Birdmap.DAL/Entities/Configurations/ServiceConfiguration.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Entities.Configurations
 | 
			
		||||
{
 | 
			
		||||
    public class ServiceConfiguration : IEntityTypeConfiguration<Service>
 | 
			
		||||
    {
 | 
			
		||||
        public void Configure(EntityTypeBuilder<Service> builder)
 | 
			
		||||
        {
 | 
			
		||||
            builder.Property(s => s.Name)
 | 
			
		||||
                .IsRequired();
 | 
			
		||||
 | 
			
		||||
            builder.Property(s => s.Uri)
 | 
			
		||||
                .HasConversion(u => u.ToString(), u => new Uri(u))
 | 
			
		||||
                .IsRequired();
 | 
			
		||||
 | 
			
		||||
            builder.HasData(
 | 
			
		||||
                new Service
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 1,
 | 
			
		||||
                    Name = "KMLabz services",
 | 
			
		||||
                    Uri = new Uri("https://birb.k8s.kmlabz.com/devices")
 | 
			
		||||
                },
 | 
			
		||||
                new Service
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 2,
 | 
			
		||||
                    Name = "Local Database",
 | 
			
		||||
                    Uri = new Uri("/health", UriKind.Relative)
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
 | 
			
		||||
using static Birdmap.Common.PasswordHelper;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Entities.Configurations
 | 
			
		||||
{
 | 
			
		||||
@@ -7,6 +8,9 @@ namespace Birdmap.DAL.Entities.Configurations
 | 
			
		||||
    {
 | 
			
		||||
        public void Configure(EntityTypeBuilder<User> builder)
 | 
			
		||||
        {
 | 
			
		||||
            builder.HasIndex(u => u.Name)
 | 
			
		||||
                .IsUnique();
 | 
			
		||||
 | 
			
		||||
            builder.Property(u => u.Name)
 | 
			
		||||
                .IsRequired();
 | 
			
		||||
 | 
			
		||||
@@ -18,6 +22,26 @@ namespace Birdmap.DAL.Entities.Configurations
 | 
			
		||||
 | 
			
		||||
            builder.Property(u => u.Role)
 | 
			
		||||
                .IsRequired();
 | 
			
		||||
 | 
			
		||||
            CreatePasswordHash("pass", out var hash, out var salt);
 | 
			
		||||
 | 
			
		||||
            builder.HasData(
 | 
			
		||||
                new User
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 1,
 | 
			
		||||
                    Name = "admin",
 | 
			
		||||
                    PasswordHash = hash,
 | 
			
		||||
                    PasswordSalt = salt,
 | 
			
		||||
                    Role = Roles.Admin,
 | 
			
		||||
                },
 | 
			
		||||
                new User
 | 
			
		||||
                {
 | 
			
		||||
                    Id = 2,
 | 
			
		||||
                    Name = "user",
 | 
			
		||||
                    PasswordHash = hash,
 | 
			
		||||
                    PasswordSalt = salt,
 | 
			
		||||
                    Role = Roles.User,
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								Birdmap.DAL/Entities/Service.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Birdmap.DAL/Entities/Service.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Entities
 | 
			
		||||
{
 | 
			
		||||
    public class Service
 | 
			
		||||
    {
 | 
			
		||||
        public int Id { get; set; }
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
        public Uri Uri { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								Birdmap.DAL/Migrations/20201025144409_InitialCreate.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								Birdmap.DAL/Migrations/20201025144409_InitialCreate.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
// <auto-generated />
 | 
			
		||||
using System;
 | 
			
		||||
using Birdmap.DAL;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Migrations
 | 
			
		||||
{
 | 
			
		||||
    [DbContext(typeof(BirdmapContext))]
 | 
			
		||||
    [Migration("20201025144409_InitialCreate")]
 | 
			
		||||
    partial class InitialCreate
 | 
			
		||||
    {
 | 
			
		||||
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
#pragma warning disable 612, 618
 | 
			
		||||
            modelBuilder
 | 
			
		||||
                .HasAnnotation("ProductVersion", "3.1.9")
 | 
			
		||||
                .HasAnnotation("Relational:MaxIdentifierLength", 128)
 | 
			
		||||
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("Birdmap.DAL.Entities.Service", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd()
 | 
			
		||||
                        .HasColumnType("int")
 | 
			
		||||
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Name")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Uri")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(max)");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Service");
 | 
			
		||||
 | 
			
		||||
                    b.HasData(
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 1,
 | 
			
		||||
                            Name = "KMLabz services",
 | 
			
		||||
                            Uri = "https://birb.k8s.kmlabz.com/devices"
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 2,
 | 
			
		||||
                            Name = "Local Database",
 | 
			
		||||
                            Uri = "/health"
 | 
			
		||||
                        });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("Birdmap.DAL.Entities.User", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd()
 | 
			
		||||
                        .HasColumnType("int")
 | 
			
		||||
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Name")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(450)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte[]>("PasswordHash")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("varbinary(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte[]>("PasswordSalt")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("varbinary(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("Role")
 | 
			
		||||
                        .HasColumnType("int");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("Name")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Users");
 | 
			
		||||
 | 
			
		||||
                    b.HasData(
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 1,
 | 
			
		||||
                            Name = "admin",
 | 
			
		||||
                            PasswordHash = new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 },
 | 
			
		||||
                            PasswordSalt = new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 },
 | 
			
		||||
                            Role = 1
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 2,
 | 
			
		||||
                            Name = "user",
 | 
			
		||||
                            PasswordHash = new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 },
 | 
			
		||||
                            PasswordSalt = new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 },
 | 
			
		||||
                            Role = 0
 | 
			
		||||
                        });
 | 
			
		||||
                });
 | 
			
		||||
#pragma warning restore 612, 618
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										74
									
								
								Birdmap.DAL/Migrations/20201025144409_InitialCreate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Birdmap.DAL/Migrations/20201025144409_InitialCreate.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Migrations
 | 
			
		||||
{
 | 
			
		||||
    public partial class InitialCreate : Migration
 | 
			
		||||
    {
 | 
			
		||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.CreateTable(
 | 
			
		||||
                name: "Service",
 | 
			
		||||
                columns: table => new
 | 
			
		||||
                {
 | 
			
		||||
                    Id = table.Column<int>(nullable: false)
 | 
			
		||||
                        .Annotation("SqlServer:Identity", "1, 1"),
 | 
			
		||||
                    Name = table.Column<string>(nullable: false),
 | 
			
		||||
                    Uri = table.Column<string>(nullable: false)
 | 
			
		||||
                },
 | 
			
		||||
                constraints: table =>
 | 
			
		||||
                {
 | 
			
		||||
                    table.PrimaryKey("PK_Service", x => x.Id);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateTable(
 | 
			
		||||
                name: "Users",
 | 
			
		||||
                columns: table => new
 | 
			
		||||
                {
 | 
			
		||||
                    Id = table.Column<int>(nullable: false)
 | 
			
		||||
                        .Annotation("SqlServer:Identity", "1, 1"),
 | 
			
		||||
                    Name = table.Column<string>(nullable: false),
 | 
			
		||||
                    PasswordHash = table.Column<byte[]>(nullable: false),
 | 
			
		||||
                    PasswordSalt = table.Column<byte[]>(nullable: false),
 | 
			
		||||
                    Role = table.Column<int>(nullable: false)
 | 
			
		||||
                },
 | 
			
		||||
                constraints: table =>
 | 
			
		||||
                {
 | 
			
		||||
                    table.PrimaryKey("PK_Users", x => x.Id);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "Service",
 | 
			
		||||
                columns: new[] { "Id", "Name", "Uri" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { 1, "KMLabz services", "https://birb.k8s.kmlabz.com/devices" },
 | 
			
		||||
                    { 2, "Local Database", "/health" }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.InsertData(
 | 
			
		||||
                table: "Users",
 | 
			
		||||
                columns: new[] { "Id", "Name", "PasswordHash", "PasswordSalt", "Role" },
 | 
			
		||||
                values: new object[,]
 | 
			
		||||
                {
 | 
			
		||||
                    { 1, "admin", new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 }, new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 }, 1 },
 | 
			
		||||
                    { 2, "user", new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 }, new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 }, 0 }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_Users_Name",
 | 
			
		||||
                table: "Users",
 | 
			
		||||
                column: "Name",
 | 
			
		||||
                unique: true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Down(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DropTable(
 | 
			
		||||
                name: "Service");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropTable(
 | 
			
		||||
                name: "Users");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								Birdmap.DAL/Migrations/BirdmapContextModelSnapshot.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								Birdmap.DAL/Migrations/BirdmapContextModelSnapshot.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
// <auto-generated />
 | 
			
		||||
using System;
 | 
			
		||||
using Birdmap.DAL;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Metadata;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL.Migrations
 | 
			
		||||
{
 | 
			
		||||
    [DbContext(typeof(BirdmapContext))]
 | 
			
		||||
    partial class BirdmapContextModelSnapshot : ModelSnapshot
 | 
			
		||||
    {
 | 
			
		||||
        protected override void BuildModel(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
#pragma warning disable 612, 618
 | 
			
		||||
            modelBuilder
 | 
			
		||||
                .HasAnnotation("ProductVersion", "3.1.9")
 | 
			
		||||
                .HasAnnotation("Relational:MaxIdentifierLength", 128)
 | 
			
		||||
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("Birdmap.DAL.Entities.Service", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd()
 | 
			
		||||
                        .HasColumnType("int")
 | 
			
		||||
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Name")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Uri")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(max)");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Service");
 | 
			
		||||
 | 
			
		||||
                    b.HasData(
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 1,
 | 
			
		||||
                            Name = "KMLabz services",
 | 
			
		||||
                            Uri = "https://birb.k8s.kmlabz.com/devices"
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 2,
 | 
			
		||||
                            Name = "Local Database",
 | 
			
		||||
                            Uri = "/health"
 | 
			
		||||
                        });
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("Birdmap.DAL.Entities.User", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd()
 | 
			
		||||
                        .HasColumnType("int")
 | 
			
		||||
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Name")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("nvarchar(450)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte[]>("PasswordHash")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("varbinary(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<byte[]>("PasswordSalt")
 | 
			
		||||
                        .IsRequired()
 | 
			
		||||
                        .HasColumnType("varbinary(max)");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("Role")
 | 
			
		||||
                        .HasColumnType("int");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("Name")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Users");
 | 
			
		||||
 | 
			
		||||
                    b.HasData(
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 1,
 | 
			
		||||
                            Name = "admin",
 | 
			
		||||
                            PasswordHash = new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 },
 | 
			
		||||
                            PasswordSalt = new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 },
 | 
			
		||||
                            Role = 1
 | 
			
		||||
                        },
 | 
			
		||||
                        new
 | 
			
		||||
                        {
 | 
			
		||||
                            Id = 2,
 | 
			
		||||
                            Name = "user",
 | 
			
		||||
                            PasswordHash = new byte[] { 182, 156, 97, 101, 71, 25, 1, 147, 227, 96, 95, 0, 109, 186, 93, 70, 175, 182, 11, 77, 231, 91, 77, 46, 38, 241, 58, 9, 217, 227, 116, 97, 153, 200, 188, 237, 136, 224, 209, 148, 211, 183, 193, 59, 248, 219, 7, 64, 215, 234, 35, 102, 226, 124, 253, 113, 109, 120, 48, 158, 62, 75, 49, 25 },
 | 
			
		||||
                            PasswordSalt = new byte[] { 113, 114, 194, 22, 187, 116, 36, 33, 217, 100, 136, 225, 215, 1, 130, 131, 192, 198, 22, 50, 117, 244, 84, 85, 171, 4, 191, 0, 110, 145, 128, 150, 48, 226, 10, 149, 26, 111, 235, 125, 150, 120, 1, 168, 228, 110, 171, 2, 202, 54, 48, 214, 65, 75, 62, 245, 108, 82, 23, 226, 118, 218, 182, 177, 223, 124, 238, 67, 191, 103, 17, 159, 139, 44, 33, 62, 183, 22, 8, 193, 222, 60, 119, 240, 85, 179, 3, 35, 125, 23, 123, 232, 214, 193, 190, 13, 53, 131, 126, 124, 15, 238, 179, 202, 98, 173, 58, 29, 118, 253, 35, 34, 80, 79, 61, 185, 226, 99, 123, 195, 50, 46, 101, 45, 246, 1, 152, 61 },
 | 
			
		||||
                            Role = 0
 | 
			
		||||
                        });
 | 
			
		||||
                });
 | 
			
		||||
#pragma warning restore 612, 618
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +1,6 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.DAL
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								Birdmap.sln
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Birdmap.sln
									
									
									
									
									
								
							@@ -5,9 +5,11 @@ VisualStudioVersion = 16.0.30611.23
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.API", "Birdmap\Birdmap.API.csproj", "{88855E5F-9555-49E5-92F2-4E8C1194F60B}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Birdmap.BLL", "Birdmap.BLL\Birdmap.BLL.csproj", "{879D7B8D-6865-4EBE-B346-E0CA37D3C06A}"
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.BLL", "Birdmap.BLL\Birdmap.BLL.csproj", "{879D7B8D-6865-4EBE-B346-E0CA37D3C06A}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}"
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Birdmap.DAL", "Birdmap.DAL\Birdmap.DAL.csproj", "{543FAB06-B960-41A9-8865-1624A2ED2170}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Birdmap.Common", "Birdmap.Common\Birdmap.Common.csproj", "{CE96BAFA-A0FD-4010-8EF2-700451091F71}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
@@ -27,6 +29,10 @@ Global
 | 
			
		||||
		{543FAB06-B960-41A9-8865-1624A2ED2170}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{543FAB06-B960-41A9-8865-1624A2ED2170}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{543FAB06-B960-41A9-8865-1624A2ED2170}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{CE96BAFA-A0FD-4010-8EF2-700451091F71}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
 
 | 
			
		||||
@@ -11,12 +11,18 @@
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="AutoMapper" Version="10.1.1" />
 | 
			
		||||
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.9" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.9" />
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.9">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.0.3">
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.3" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Microsoft.IdentityModel.Tokens;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IdentityModel.Tokens.Jwt;
 | 
			
		||||
@@ -23,12 +24,14 @@ namespace Birdmap.Controllers
 | 
			
		||||
        private readonly IAuthService _service;
 | 
			
		||||
        private readonly IConfiguration _configuration;
 | 
			
		||||
        private readonly IMapper _mapper;
 | 
			
		||||
        private readonly ILogger<AuthController> _logger;
 | 
			
		||||
 | 
			
		||||
        public AuthController(IAuthService service, IConfiguration configuration, IMapper mapper)
 | 
			
		||||
        public AuthController(IAuthService service, IConfiguration configuration, IMapper mapper, ILogger<AuthController> logger)
 | 
			
		||||
        {
 | 
			
		||||
            _service = service;
 | 
			
		||||
            _configuration = configuration;
 | 
			
		||||
            _mapper = mapper;
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [AllowAnonymous]
 | 
			
		||||
@@ -36,7 +39,12 @@ namespace Birdmap.Controllers
 | 
			
		||||
        [ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
 | 
			
		||||
        public async Task<IActionResult> AuthenticateAsync([FromBody] AuthenticateRequest model)
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogInformation($"Authenticating user [{model.Username}] with password [*******]...");
 | 
			
		||||
 | 
			
		||||
            var user = await _service.AuthenticateUserAsync(model.Username, model.Password);
 | 
			
		||||
 | 
			
		||||
            _logger.LogInformation($"Authenticated user [{user.Name}]. Returning token...");
 | 
			
		||||
 | 
			
		||||
            var expiresInSeconds = TimeSpan.FromHours(2).TotalSeconds;
 | 
			
		||||
            var tokenHandler = new JwtSecurityTokenHandler();
 | 
			
		||||
            var key = Encoding.ASCII.GetBytes(_configuration["Secret"]);
 | 
			
		||||
@@ -60,5 +68,17 @@ namespace Birdmap.Controllers
 | 
			
		||||
 | 
			
		||||
            return Ok(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [AllowAnonymous]
 | 
			
		||||
        [HttpPost("register")]
 | 
			
		||||
        [ProducesResponseType(StatusCodes.Status204NoContent)]
 | 
			
		||||
        public async Task<IActionResult> RegisterAsync([FromBody] RegisterRequest model)
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogInformation($"Registering user [{model.Username}]...");
 | 
			
		||||
            var created = await _service.RegisterUserAsync(model.Username, model.Password);
 | 
			
		||||
 | 
			
		||||
            _logger.LogInformation($"Registered user [{created.Id}.");
 | 
			
		||||
            return NoContent();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								Birdmap/DTOs/RegisterRequest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Birdmap/DTOs/RegisterRequest.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
using System.ComponentModel.DataAnnotations;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.API.DTOs
 | 
			
		||||
{
 | 
			
		||||
    public class RegisterRequest
 | 
			
		||||
    {
 | 
			
		||||
        [Required(AllowEmptyStrings = false, ErrorMessage = "Username is required.")]
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Required(AllowEmptyStrings = false, ErrorMessage = "Password is required."), DataType(DataType.Password)]
 | 
			
		||||
        public string Password { get; set; }
 | 
			
		||||
 | 
			
		||||
        [Required(AllowEmptyStrings = false, ErrorMessage = "Please confirm password.")]
 | 
			
		||||
        [DataType(DataType.Password), Compare(nameof(Password), ErrorMessage = "Passwords did not match.")]
 | 
			
		||||
        public string ConfirmPassword { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								Birdmap/Middlewares/ExceptionHandlerMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Birdmap/Middlewares/ExceptionHandlerMiddleware.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
using Birdmap.BLL.Exceptions;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.API.Middlewares
 | 
			
		||||
{
 | 
			
		||||
    public class ExceptionHandlerMiddleware
 | 
			
		||||
    {
 | 
			
		||||
        private readonly RequestDelegate _next;
 | 
			
		||||
        private readonly ILogger<ExceptionHandlerMiddleware> _logger;
 | 
			
		||||
 | 
			
		||||
        public ExceptionHandlerMiddleware(RequestDelegate next, ILogger<ExceptionHandlerMiddleware> logger)
 | 
			
		||||
        {
 | 
			
		||||
            _next = next;
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Invoke(HttpContext context)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                await _next(context);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                await HandleException(context, ex);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task HandleException(HttpContext context, Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            _logger.LogWarning(ex, "");
 | 
			
		||||
 | 
			
		||||
            var code = ex switch
 | 
			
		||||
            {
 | 
			
		||||
                AuthenticationException _ => HttpStatusCode.Unauthorized,
 | 
			
		||||
                EntityNotFoundException _ => HttpStatusCode.NotFound,
 | 
			
		||||
                ArgumentException _ => HttpStatusCode.BadRequest,
 | 
			
		||||
                DbUpdateConcurrencyException _ => HttpStatusCode.Conflict,
 | 
			
		||||
                _ => HttpStatusCode.InternalServerError,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            var result = JsonConvert.SerializeObject(new { error = ex.Message, exception = ex.ToString() });
 | 
			
		||||
 | 
			
		||||
            context.Response.ContentType = "application/json";
 | 
			
		||||
            context.Response.StatusCode = (int)code;
 | 
			
		||||
 | 
			
		||||
            return context.Response.WriteAsync(result);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
@page
 | 
			
		||||
@model ErrorModel
 | 
			
		||||
@{
 | 
			
		||||
    ViewData["Title"] = "Error";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<h1 class="text-danger">Error.</h1>
 | 
			
		||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
 | 
			
		||||
 | 
			
		||||
@if (Model.ShowRequestId)
 | 
			
		||||
{
 | 
			
		||||
    <p>
 | 
			
		||||
        <strong>Request ID:</strong> <code>@Model.RequestId</code>
 | 
			
		||||
    </p>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<h3>Development Mode</h3>
 | 
			
		||||
<p>
 | 
			
		||||
    Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
 | 
			
		||||
</p>
 | 
			
		||||
<p>
 | 
			
		||||
    <strong>The Development environment shouldn't be enabled for deployed applications.</strong>
 | 
			
		||||
    It can result in displaying sensitive information from exceptions to end users.
 | 
			
		||||
    For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
 | 
			
		||||
    and restarting the app.
 | 
			
		||||
</p>
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.RazorPages;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap.Pages
 | 
			
		||||
{
 | 
			
		||||
    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
 | 
			
		||||
    public class ErrorModel : PageModel
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger<ErrorModel> logger;
 | 
			
		||||
 | 
			
		||||
        public ErrorModel(ILogger<ErrorModel> _logger)
 | 
			
		||||
        {
 | 
			
		||||
            logger = _logger;
 | 
			
		||||
        }
 | 
			
		||||
        public string RequestId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
 | 
			
		||||
 | 
			
		||||
        public void OnGet()
 | 
			
		||||
        {
 | 
			
		||||
            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
@using Birdmap
 | 
			
		||||
@namespace Birdmap.Pages
 | 
			
		||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
 | 
			
		||||
@@ -1,11 +1,9 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.Hosting;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
using NLog;
 | 
			
		||||
using NLog.Web;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Birdmap
 | 
			
		||||
{
 | 
			
		||||
@@ -13,14 +11,35 @@ namespace Birdmap
 | 
			
		||||
    {
 | 
			
		||||
        public static void Main(string[] args)
 | 
			
		||||
        {
 | 
			
		||||
            var logger = NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                logger.Debug("Main called...");
 | 
			
		||||
                CreateHostBuilder(args).Build().Run();
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error(ex, "Exception occurred in Main.");
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                LogManager.Shutdown();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static IHostBuilder CreateHostBuilder(string[] args) =>
 | 
			
		||||
            Host.CreateDefaultBuilder(args)
 | 
			
		||||
                .ConfigureWebHostDefaults(webBuilder =>
 | 
			
		||||
                {
 | 
			
		||||
                    webBuilder.UseStartup<Startup>();
 | 
			
		||||
                });
 | 
			
		||||
                }).ConfigureLogging(logging =>
 | 
			
		||||
                {
 | 
			
		||||
                    logging.ClearProviders();
 | 
			
		||||
                    logging.AddConsole();
 | 
			
		||||
                    logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
 | 
			
		||||
                })
 | 
			
		||||
                .UseNLog();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
using AutoMapper;
 | 
			
		||||
using Birdmap.API.Middlewares;
 | 
			
		||||
using Birdmap.BLL;
 | 
			
		||||
using Birdmap.BLL.Interfaces;
 | 
			
		||||
using Birdmap.DAL;
 | 
			
		||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
@@ -34,6 +35,8 @@ namespace Birdmap
 | 
			
		||||
            services.ConfigureBLL(Configuration);
 | 
			
		||||
            services.ConfigureDAL(Configuration);
 | 
			
		||||
 | 
			
		||||
            services.AddAutoMapper(typeof(Startup));
 | 
			
		||||
 | 
			
		||||
            var key = Encoding.ASCII.GetBytes(Configuration["Secret"]);
 | 
			
		||||
            services.AddAuthentication(opt =>
 | 
			
		||||
            {
 | 
			
		||||
@@ -70,9 +73,7 @@ namespace Birdmap
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                app.UseExceptionHandler("/Error");
 | 
			
		||||
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
 | 
			
		||||
                app.UseHsts();
 | 
			
		||||
                app.UseMiddleware<ExceptionHandlerMiddleware>();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            app.UseHttpsRedirection();
 | 
			
		||||
@@ -86,6 +87,7 @@ namespace Birdmap
 | 
			
		||||
 | 
			
		||||
            app.UseEndpoints(endpoints =>
 | 
			
		||||
            {
 | 
			
		||||
                endpoints.MapHealthChecks("/health").RequireAuthorization();
 | 
			
		||||
                endpoints.MapControllers();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,24 +8,5 @@
 | 
			
		||||
  },
 | 
			
		||||
  "AllowedHosts": "*",
 | 
			
		||||
  "Secret": "7vj.3KW.hYE!}4u6",
 | 
			
		||||
  "LocalDbConnectionString": null,
 | 
			
		||||
  "Default": {
 | 
			
		||||
    "Users": [
 | 
			
		||||
      {
 | 
			
		||||
        "Username": "user",
 | 
			
		||||
        "Password": "pass",
 | 
			
		||||
        "Role": "User"
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        "Username": "admin",
 | 
			
		||||
        "Password": "pass",
 | 
			
		||||
        "Role": "Admin"
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    "Endpoints": [
 | 
			
		||||
      "",
 | 
			
		||||
      "",
 | 
			
		||||
      ""
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
  "LocalDbConnectionString": "Data Source=DESKTOP-A6JQ6B5\\SQLEXPRESS;Initial Catalog=Birdmap;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								Birdmap/nlog.config
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								Birdmap/nlog.config
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8" ?>
 | 
			
		||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
 | 
			
		||||
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 | 
			
		||||
      autoReload="true"
 | 
			
		||||
      internalLogLevel="Info"
 | 
			
		||||
      internalLogFile="${basedir}Log/internal-nlog.txt"
 | 
			
		||||
      throwConfigExceptions="true">
 | 
			
		||||
 | 
			
		||||
  <!-- enable asp.net core layout renderers -->
 | 
			
		||||
  <extensions>
 | 
			
		||||
    <add assembly="NLog.Web.AspNetCore"/>
 | 
			
		||||
  </extensions>
 | 
			
		||||
 | 
			
		||||
  <!-- the targets to write to -->
 | 
			
		||||
  <targets async="true">
 | 
			
		||||
    <default-target-parameters xsi:type="File" keepFileOpen="false" maxArchiveFiles="10" archiveAboveSize="1048576"/>
 | 
			
		||||
    <target xsi:type="File" name="allfile" fileName="${basedir}Log/birdmap-all-${shortdate}.log"
 | 
			
		||||
            layout="${longdate} [${event-properties:item=EventId_Id}] ${uppercase:${level}} ${logger} - ${message} ${exception:format=tostring}" />
 | 
			
		||||
 | 
			
		||||
    <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
 | 
			
		||||
    <target xsi:type="File" name="ownFile" fileName="${basedir}Log/birdmap-own-${shortdate}.log"
 | 
			
		||||
            layout="${longdate} [${event-properties:item=EventId_Id}] ${uppercase:${level}} ${callsite} - ${message} ${exception:format=tostring} (url: ${aspnet-request-url})(action: ${aspnet-mvc-action})" />
 | 
			
		||||
  </targets>
 | 
			
		||||
 | 
			
		||||
  <!-- rules to map from logger name to target +-->
 | 
			
		||||
  <rules>
 | 
			
		||||
    <!--All logs, including from Microsoft-->
 | 
			
		||||
    <logger name="*" minlevel="Trace" writeTo="allfile" />
 | 
			
		||||
 | 
			
		||||
    <!--Skip non-critical Microsoft logs and so log only own logs-->
 | 
			
		||||
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
 | 
			
		||||
    <!-- BlackHole without writeTo -->
 | 
			
		||||
    <logger name="*" minlevel="Trace" writeTo="ownFile" />
 | 
			
		||||
  </rules>
 | 
			
		||||
</nlog>
 | 
			
		||||
		Reference in New Issue
	
	Block a user