diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs
index 7f77bcaeb4..af474d2060 100644
--- a/src/Api/Startup.cs
+++ b/src/Api/Startup.cs
@@ -14,13 +14,13 @@ using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json.Serialization;
using AspNetCoreRateLimit;
-using Bit.Api.Middleware;
using Serilog.Events;
using Stripe;
using Bit.Core.Utilities;
using IdentityModel;
using IdentityServer4.AccessTokenValidation;
using jsreport.AspNetCore;
+using Bit.Core.IdentityServer;
namespace Bit.Api
{
diff --git a/src/Api/Utilities/TokenRetrieval.cs b/src/Core/IdentityServer/TokenRetrieval.cs
similarity index 97%
rename from src/Api/Utilities/TokenRetrieval.cs
rename to src/Core/IdentityServer/TokenRetrieval.cs
index fbfeec829d..b16708640d 100644
--- a/src/Api/Utilities/TokenRetrieval.cs
+++ b/src/Core/IdentityServer/TokenRetrieval.cs
@@ -2,7 +2,7 @@
using System;
using System.Linq;
-namespace Bit.Api.Utilities
+namespace Bit.Core.IdentityServer
{
public static class TokenRetrieval
{
diff --git a/src/Api/Middleware/CurrentContextMiddleware.cs b/src/Core/Utilities/CurrentContextMiddleware.cs
similarity index 97%
rename from src/Api/Middleware/CurrentContextMiddleware.cs
rename to src/Core/Utilities/CurrentContextMiddleware.cs
index 346c30d38a..1b12ef5b4c 100644
--- a/src/Api/Middleware/CurrentContextMiddleware.cs
+++ b/src/Core/Utilities/CurrentContextMiddleware.cs
@@ -1,12 +1,11 @@
-using Bit.Core;
-using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
-namespace Bit.Api.Middleware
+namespace Bit.Core.Utilities
{
public class CurrentContextMiddleware
{
diff --git a/src/Events/Controllers/EventsController.cs b/src/Events/Controllers/EventsController.cs
index 5cef2ef38a..637c2a1570 100644
--- a/src/Events/Controllers/EventsController.cs
+++ b/src/Events/Controllers/EventsController.cs
@@ -1,13 +1,45 @@
using System;
+using System.Threading.Tasks;
+using Bit.Core;
+using Bit.Core.Repositories;
+using Bit.Core.Services;
+using Bit.Events.Models;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Events.Controllers
{
+ [Authorize("Application")]
public class EventsController : Controller
{
- [HttpPost("~/")]
- public void Post([FromBody]string value)
+ private readonly CurrentContext _currentContext;
+ private readonly IEventService _eventService;
+ private readonly ICipherRepository _cipherRepository;
+
+ public EventsController(
+ CurrentContext currentContext,
+ IEventService eventService,
+ ICipherRepository cipherRepository)
{
+ _currentContext = currentContext;
+ _eventService = eventService;
+ _cipherRepository = cipherRepository;
+ }
+
+ [HttpPost("~/cipher/{id}")]
+ public async Task PostCipher(Guid id, [FromBody]EventModel model)
+ {
+ var cipher = await _cipherRepository.GetByIdAsync(id, _currentContext.UserId.Value);
+ if(cipher != null)
+ {
+ await _eventService.LogCipherEventAsync(cipher, model.Type);
+ }
+ }
+
+ [HttpPost("~/user")]
+ public async Task PostUser([FromBody]EventModel model)
+ {
+ await _eventService.LogUserEventAsync(_currentContext.UserId.Value, model.Type);
}
}
}
diff --git a/src/Events/Events.csproj b/src/Events/Events.csproj
index 91c4796c73..f430c78929 100644
--- a/src/Events/Events.csproj
+++ b/src/Events/Events.csproj
@@ -9,6 +9,7 @@
+
@@ -17,4 +18,8 @@
+
+
+
+
diff --git a/src/Events/Models/EventModel.cs b/src/Events/Models/EventModel.cs
new file mode 100644
index 0000000000..d75035ec98
--- /dev/null
+++ b/src/Events/Models/EventModel.cs
@@ -0,0 +1,10 @@
+using System;
+using Bit.Core.Enums;
+
+namespace Bit.Events.Models
+{
+ public class EventModel
+ {
+ public EventType Type { get; set; }
+ }
+}
diff --git a/src/Events/Startup.cs b/src/Events/Startup.cs
index e464b6af9e..6d905f0bed 100644
--- a/src/Events/Startup.cs
+++ b/src/Events/Startup.cs
@@ -1,36 +1,119 @@
-using System;
+using System.Security.Claims;
+using Bit.Core;
+using Bit.Core.IdentityServer;
+using Bit.Core.Services;
+using Bit.Core.Utilities;
+using IdentityModel;
+using IdentityServer4.AccessTokenValidation;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Serilog.Events;
namespace Bit.Events
{
public class Startup
{
- public Startup(IConfiguration configuration)
+ public Startup(IHostingEnvironment env, IConfiguration configuration)
{
Configuration = configuration;
+ Environment = env;
}
public IConfiguration Configuration { get; }
+ public IHostingEnvironment Environment { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Options
services.AddOptions();
+ // Settings
+ var globalSettings = services.AddGlobalSettingsServices(Configuration);
+
+ // Repositories
+ services.AddSqlServerRepositories(globalSettings);
+
+ // Context
+ services.AddScoped();
+
+ // Identity
+ services
+ .AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
+ .AddIdentityServerAuthentication(options =>
+ {
+ options.Authority = globalSettings.BaseServiceUri.InternalIdentity;
+ options.RequireHttpsMetadata = !Environment.IsDevelopment() &&
+ globalSettings.BaseServiceUri.InternalIdentity.StartsWith("https");
+ options.NameClaimType = ClaimTypes.Email;
+ options.TokenRetriever = TokenRetrieval.FromAuthorizationHeaderOrQueryString(
+ new string[] { "Bearer", "Bearer3" });
+ options.SupportedTokens = SupportedTokens.Jwt;
+ });
+
+ services.AddAuthorization(config =>
+ {
+ config.AddPolicy("Application", policy =>
+ {
+ policy.RequireAuthenticatedUser();
+ policy.RequireClaim(JwtClaimTypes.AuthenticationMethod, "Application");
+ });
+ });
+
+ // Services
+ services.AddScoped();
+ if(!globalSettings.SelfHosted && CoreHelpers.SettingHasValue(globalSettings.Storage.ConnectionString))
+ {
+ services.AddSingleton();
+ }
+ else
+ {
+ services.AddSingleton();
+ }
+
// Mvc
services.AddMvc();
}
- public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+ public void Configure(
+ IApplicationBuilder app,
+ IHostingEnvironment env,
+ ILoggerFactory loggerFactory,
+ IApplicationLifetime appLifetime,
+ GlobalSettings globalSettings)
{
+ loggerFactory.AddSerilog(env, appLifetime, globalSettings, (e) =>
+ {
+ var context = e.Properties["SourceContext"].ToString();
+ if(context.Contains("IdentityServer4.Validation.TokenValidator") ||
+ context.Contains("IdentityServer4.Validation.TokenRequestValidator"))
+ {
+ return e.Level > LogEventLevel.Error;
+ }
+
+ return e.Level >= LogEventLevel.Error;
+ });
+
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
+ // Default Middleware
+ app.UseDefaultMiddleware(env);
+
+ // Add Cors
+ app.UseCors("All");
+
+ // Add authentication to the request pipeline.
+ app.UseAuthentication();
+
+ // Add current context
+ app.UseMiddleware();
+
+ // Add MVC to the request pipeline.
app.UseMvc();
}
}
diff --git a/src/Events/appsettings.Development.json b/src/Events/appsettings.Development.json
deleted file mode 100644
index fa8ce71a97..0000000000
--- a/src/Events/appsettings.Development.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "Logging": {
- "IncludeScopes": false,
- "LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
- }
- }
-}
diff --git a/src/Events/appsettings.Preview.json b/src/Events/appsettings.Preview.json
new file mode 100644
index 0000000000..ebe1db52d5
--- /dev/null
+++ b/src/Events/appsettings.Preview.json
@@ -0,0 +1,10 @@
+{
+ "globalSettings": {
+ "baseServiceUri": {
+ "vault": "https://preview-vault.bitwarden.com",
+ "api": "https://preview-api.bitwarden.com",
+ "identity": "https://preview-identity.bitwarden.com",
+ "internalIdentity": "https://preview-identity.bitwarden.com"
+ }
+ }
+}
diff --git a/src/Events/appsettings.Production.json b/src/Events/appsettings.Production.json
new file mode 100644
index 0000000000..87ace9ae2a
--- /dev/null
+++ b/src/Events/appsettings.Production.json
@@ -0,0 +1,10 @@
+{
+ "globalSettings": {
+ "baseServiceUri": {
+ "vault": "https://vault.bitwarden.com",
+ "api": "https://api.bitwarden.com",
+ "identity": "https://identity.bitwarden.com",
+ "internalIdentity": "https://identity.bitwarden.com"
+ }
+ }
+}
diff --git a/src/Events/appsettings.Staging.json b/src/Events/appsettings.Staging.json
new file mode 100644
index 0000000000..87ace9ae2a
--- /dev/null
+++ b/src/Events/appsettings.Staging.json
@@ -0,0 +1,10 @@
+{
+ "globalSettings": {
+ "baseServiceUri": {
+ "vault": "https://vault.bitwarden.com",
+ "api": "https://api.bitwarden.com",
+ "identity": "https://identity.bitwarden.com",
+ "internalIdentity": "https://identity.bitwarden.com"
+ }
+ }
+}
diff --git a/src/Events/appsettings.json b/src/Events/appsettings.json
index 26bb0ac7ac..0d06d7dfe3 100644
--- a/src/Events/appsettings.json
+++ b/src/Events/appsettings.json
@@ -1,15 +1,25 @@
{
- "Logging": {
- "IncludeScopes": false,
- "Debug": {
- "LogLevel": {
- "Default": "Warning"
- }
+ "globalSettings": {
+ "selfHosted": false,
+ "projectName": "Events",
+ "baseServiceUri": {
+ "vault": "http://localhost:4001",
+ "api": "http://localhost:4000",
+ "identity": "http://localhost:33656",
+ "internalIdentity": "http://localhost:33656"
},
- "Console": {
- "LogLevel": {
- "Default": "Warning"
- }
+ "sqlServer": {
+ "connectionString": "SECRET"
+ },
+ "identityServer": {
+ "certificateThumbprint": "SECRET"
+ },
+ "storage": {
+ "connectionString": "SECRET"
+ },
+ "documentDb": {
+ "uri": "SECRET",
+ "key": "SECRET"
}
}
}