1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-04 03:02:18 -05:00
bitwarden/src/Api/Utilities/ServiceCollectionExtensions.cs
Conner Turnbull cf7a59c077
[Innovation Sprint] Phishing Detection (#5516)
* Initial stubbing out of the phishing service

* Add the phishing domain controller

* Add changes for the phishing domain get

* Add distributed cache to the phishing domain

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* Rename the variable name

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>

* Removed IPhishingDomainService

* Feature/phishing detection cronjob (#5512)

* Added caching to EF implementation. Added error handling and logging

* Refactored update method to use sqlbulkcopy instead of performing a round trip for each new insert

* Initial implementation for quartz job to get list of phishing domains

* Updated phishing domain settings to be its own interface

* Add phishing domain detection with checksum-based updates

* Updated auth for phishing domain endpoints to either require api, or licensing claims to support both web and browser clients, and selfhost api clients

* [Innovation Sprint] Updated Phishing domains to rely on blob storage (#5517)

* Updated phishing detection data layer to rely on azure blob storage instead of sql server

* dotnet format

* Took rider refactors

* Ensuring phishing.testcategory.com exists to test against

* Added redis to dev's docker-compose

* Removed redis from cloud profile

* Remove the Authorize attribute

* error whitespace fix whitespace formatting

* error WHITESPACE: Fix whitespace formatting

* Wrapped phishing detection feature behind feature flag (#5532)

* Increased timeout for fetching source list a bunch

* Removed PhishingDomains policy

---------

Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
Co-authored-by: Cy Okeke <cokeke@bitwarden.com>
2025-04-30 11:03:59 -04:00

138 lines
5.4 KiB
C#

using Bit.Api.AdminConsole.Authorization;
using Bit.Api.Tools.Authorization;
using Bit.Api.Vault.AuthorizationHandlers.Collections;
using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Authorization;
using Bit.Core.IdentityServer;
using Bit.Core.PhishingDomainFeatures;
using Bit.Core.PhishingDomainFeatures.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Repositories.Implementations;
using Bit.Core.Settings;
using Bit.Core.Utilities;
using Bit.Core.Vault.Authorization.SecurityTasks;
using Bit.SharedWeb.Health;
using Bit.SharedWeb.Swagger;
using Microsoft.AspNetCore.Authorization;
using Microsoft.OpenApi.Models;
namespace Bit.Api.Utilities;
public static class ServiceCollectionExtensions
{
public static void AddSwagger(this IServiceCollection services, GlobalSettings globalSettings)
{
services.AddSwaggerGen(config =>
{
config.SwaggerDoc("public", new OpenApiInfo
{
Title = "Bitwarden Public API",
Version = "latest",
Contact = new OpenApiContact
{
Name = "Bitwarden Support",
Url = new Uri("https://bitwarden.com"),
Email = "support@bitwarden.com"
},
Description = "The Bitwarden public APIs.",
License = new OpenApiLicense
{
Name = "GNU Affero General Public License v3.0",
Url = new Uri("https://github.com/bitwarden/server/blob/master/LICENSE.txt")
}
});
config.SwaggerDoc("internal", new OpenApiInfo { Title = "Bitwarden Internal API", Version = "latest" });
config.AddSecurityDefinition("oauth2-client-credentials", new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
ClientCredentials = new OpenApiOAuthFlow
{
TokenUrl = new Uri($"{globalSettings.BaseServiceUri.Identity}/connect/token"),
Scopes = new Dictionary<string, string>
{
{ ApiScopes.ApiOrganization, "Organization APIs" },
},
}
},
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "oauth2-client-credentials"
},
},
new[] { ApiScopes.ApiOrganization }
}
});
config.DescribeAllParametersInCamelCase();
// config.UseReferencedDefinitionsForEnums();
config.SchemaFilter<EnumSchemaFilter>();
var apiFilePath = Path.Combine(AppContext.BaseDirectory, "Api.xml");
config.IncludeXmlComments(apiFilePath, true);
var coreFilePath = Path.Combine(AppContext.BaseDirectory, "Core.xml");
config.IncludeXmlComments(coreFilePath);
});
}
public static void AddHealthChecks(this IServiceCollection services, GlobalSettings globalSettings)
{
services.AddHealthCheckServices(globalSettings, builder =>
{
var identityUri = new Uri(globalSettings.BaseServiceUri.Identity
+ "/.well-known/openid-configuration");
builder.AddUrlGroup(identityUri, "identity");
if (CoreHelpers.SettingHasValue(globalSettings.SqlServer.ConnectionString))
{
builder.AddSqlServer(globalSettings.SqlServer.ConnectionString);
}
});
}
public static void AddAuthorizationHandlers(this IServiceCollection services)
{
services.AddScoped<IAuthorizationHandler, BulkCollectionAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, CollectionAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, GroupAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, VaultExportAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, SecurityTaskAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, SecurityTaskOrganizationAuthorizationHandler>();
services.AddScoped<IAuthorizationHandler, OrganizationRequirementHandler>();
}
public static void AddPhishingDomainServices(this IServiceCollection services, GlobalSettings globalSettings)
{
services.AddHttpClient("PhishingDomains", client =>
{
client.DefaultRequestHeaders.Add("User-Agent", globalSettings.SelfHosted ? "Bitwarden Self-Hosted" : "Bitwarden");
client.Timeout = TimeSpan.FromSeconds(1000); // the source list is very slow
});
services.AddSingleton<AzurePhishingDomainStorageService>();
services.AddSingleton<IPhishingDomainRepository, AzurePhishingDomainRepository>();
if (globalSettings.SelfHosted)
{
services.AddScoped<ICloudPhishingDomainQuery, CloudPhishingDomainRelayQuery>();
}
else
{
services.AddScoped<ICloudPhishingDomainQuery, CloudPhishingDomainDirectQuery>();
}
}
}