mirror of
https://github.com/bitwarden/server.git
synced 2025-07-02 08:32:50 -05:00
Add Icons application for serving website icons.
This commit is contained in:
75
src/Icons/Controllers/IconController.cs
Normal file
75
src/Icons/Controllers/IconController.cs
Normal file
@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using System.Threading.Tasks;
|
||||
using Icons.Models;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Icons.Controllers
|
||||
{
|
||||
[Route("[controller]")]
|
||||
public class IconController : Controller
|
||||
{
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
public IconController(IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<FileResult> Get([FromQuery] string domain)
|
||||
{
|
||||
var uri = BuildUrl(domain);
|
||||
var fileName = $"{_hostingEnvironment.ContentRootPath}/cache/{domain}.cache";
|
||||
|
||||
// Attempt to load the icon from the cache.
|
||||
if (FileExists(fileName))
|
||||
{
|
||||
using (Stream stream = System.IO.File.Open(fileName, FileMode.Open))
|
||||
{
|
||||
var binaryFormatter = new BinaryFormatter();
|
||||
var icon = (Icon)binaryFormatter.Deserialize(stream);
|
||||
|
||||
if (icon.HasNotExpired())
|
||||
{
|
||||
return new FileContentResult(icon.Image, icon.Format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var httpClient = new HttpClient();
|
||||
var response = await httpClient.GetAsync(uri);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception("Cannot load the image");
|
||||
}
|
||||
|
||||
// Serialize the icon.
|
||||
using (Stream stream = System.IO.File.Open(fileName, FileMode.Create))
|
||||
{
|
||||
var icon = new Icon(
|
||||
await response.Content.ReadAsByteArrayAsync(),
|
||||
response.Content.Headers.ContentType.MediaType
|
||||
);
|
||||
|
||||
var binaryFormatter = new BinaryFormatter();
|
||||
binaryFormatter.Serialize(stream, icon);
|
||||
return new FileContentResult(icon.Image, icon.Format);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool FileExists(string fileName)
|
||||
{
|
||||
return System.IO.File.Exists(fileName);
|
||||
}
|
||||
|
||||
private static string BuildUrl(string domain)
|
||||
{
|
||||
return $"https://icons.bitwarden.com/icon?url={domain}&size=16..24..200";
|
||||
}
|
||||
}
|
||||
}
|
19
src/Icons/Icons.csproj
Normal file
19
src/Icons/Icons.csproj
Normal file
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
31
src/Icons/Models/Icon.cs
Normal file
31
src/Icons/Models/Icon.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Icons.Models
|
||||
{
|
||||
[Serializable]
|
||||
public class Icon
|
||||
{
|
||||
|
||||
public byte[] Image { get; }
|
||||
|
||||
public string Format { get; }
|
||||
|
||||
public DateTime CreatedAt { get; }
|
||||
|
||||
public Icon(byte[] image, string format)
|
||||
{
|
||||
this.Image = image;
|
||||
this.Format = format;
|
||||
this.CreatedAt = DateTime.Now;
|
||||
}
|
||||
|
||||
public bool HasNotExpired()
|
||||
{
|
||||
return CreatedAt > DateTime.Now.AddDays(-1);
|
||||
}
|
||||
}
|
||||
}
|
25
src/Icons/Program.cs
Normal file
25
src/Icons/Program.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Icons
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
BuildWebHost(args).Run();
|
||||
}
|
||||
|
||||
public static IWebHost BuildWebHost(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args)
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
}
|
||||
}
|
29
src/Icons/Properties/launchSettings.json
Normal file
29
src/Icons/Properties/launchSettings.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:50024/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "icon?domain=bitwarden.com",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"Icons": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "icon?domain=bitwarden.com",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:50025/"
|
||||
}
|
||||
}
|
||||
}
|
40
src/Icons/Startup.cs
Normal file
40
src/Icons/Startup.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Icons
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseMvc();
|
||||
}
|
||||
}
|
||||
}
|
10
src/Icons/appsettings.Development.json
Normal file
10
src/Icons/appsettings.Development.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
15
src/Icons/appsettings.json
Normal file
15
src/Icons/appsettings.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"Debug": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
},
|
||||
"Console": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user