-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSimplePasscode.cs
More file actions
92 lines (87 loc) · 3.35 KB
/
SimplePasscode.cs
File metadata and controls
92 lines (87 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace SimplePasscode
{
public class SimplePasscodeOptions
{
public string Passcode { get; set; }
public string CookieName { get; set; } = "app_passcode";
public string LoginPath { get; set; } = "/passcode";
public string LoginPageFile { get; set; } = "passcode.html";
public Func<HttpContext, bool> Filter { get; set; }
}
public class SimplePasscodeMiddleware
{
private readonly RequestDelegate next;
private readonly ILogger<SimplePasscodeMiddleware> logger;
private readonly SimplePasscodeOptions options;
public SimplePasscodeMiddleware(SimplePasscodeOptions options,
RequestDelegate next, ILogger<SimplePasscodeMiddleware> logger)
{
this.options = options;
this.next = next;
this.logger = logger;
}
public async Task InvokeAsync(HttpContext ctx)
{
var req = ctx.Request;
var resp = ctx.Response;
if (req.Method == "POST" && req.Path == options.LoginPath)
{
var form = await req.ReadFormAsync();
if (form != null && form["passcode"] == options.Passcode)
{
resp.Cookies.Append(options.CookieName, form["passcode"], new CookieOptions
{
Expires = DateTime.Now.AddDays(14)
});
resp.Redirect("/");
return;
}
else
{
logger.LogWarning("Wrong passcode from {ip}:{port} {id}",
ctx.Connection.RemoteIpAddress, ctx.Connection.RemotePort, ctx.TraceIdentifier);
}
}
else if (req.Method == "GET" && req.Path == options.LoginPath)
{
resp.StatusCode = 403;
var accepts = req.Headers["Accept"];
bool acceptHtml = accepts.Any(x => x.Split(',').Contains("text/html"));
if (acceptHtml)
{
resp.ContentType = "text/html";
using (var fs = File.OpenRead(options.LoginPageFile))
{
resp.ContentLength = fs.Length;
await fs.CopyToAsync(resp.Body);
}
}
else
{
resp.ContentType = "text/plain";
await resp.Body.WriteAsync(Encoding.UTF8.GetBytes("passcode_missing"));
}
return;
}
resp.Redirect(options.LoginPath);
}
}
public static class SimplePasscodeExtensions
{
public static void UsePasscode(this IApplicationBuilder app, SimplePasscodeOptions options)
{
app.UseWhen(
(ctx) => ctx.Request.Cookies[options.CookieName] != options.Passcode
&& options.Filter?.Invoke(ctx) != false,
app => app.UseMiddleware<SimplePasscodeMiddleware>(options));
}
}
}