summaryrefslogtreecommitdiff
path: root/Server/Services/UserService.cs
blob: 9e79dc6ab4562939be360e3954c5425e276375b3 (plain)
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
using Microsoft.AspNetCore.Cryptography.KeyDerivation;

namespace HyperBooru.Services;

public interface IUserService {
    public UserSessionState UserSessionState { get; }
}

public class UserService : IUserService {
    public UserSessionState UserSessionState =>
        globalUserService.GetSessionState(httpContext.Session.Id);

    private IHttpContextAccessor         httpContextAccessor;
    private IGlobalUserService           globalUserService;

    private HttpContext httpContext =>
        httpContextAccessor.HttpContext!;

    public UserService(
        IHttpContextAccessor httpContextAccessor,
        IGlobalUserService globalUserService) {

        this.httpContextAccessor = httpContextAccessor;
        this.globalUserService   = globalUserService;

        // HTTP context session states are discarded if no values
        // are set. Set a dummy value so that the session state
        // will not be discarded later when we actually need it.
        httpContext.Session.SetInt32("Persist", 1);
    }

    public static string HashPassword(string password) =>
        Convert.ToBase64String(
            KeyDerivation.Pbkdf2(
                password,
                Array.Empty<byte>(),
                KeyDerivationPrf.HMACSHA512,
                100_000,
                512 / 8));
}

public interface IGlobalUserService {
    public UserSessionState GetSessionState(string id);
}

public class GlobalUserService : IGlobalUserService {
    // TODO: prune this list periodically
    private Dictionary<string, UserSessionState> sessionStates = new();

    public UserSessionState GetSessionState(string id) {
        sessionStates.TryGetValue(id, out var state);

        if(state is null) {
            state = new();
            sessionStates[id] = state;
        }

        return state;
    }
}

public record UserSessionState {
    public event UserSessionStateChange OnStateChange;

    public bool ShowNsfw {
        get => showNsfw;
        set {
            showNsfw = value;
            OnStateChange.Invoke(this);
        }
    }

    private bool showNsfw = false;
}

public delegate void UserSessionStateChange(UserSessionState sessionState);