main 6af0a61

encryption.go RawHistoryFolder

1package disk
2
3import (
4	"errors"
5
6	"github.com/bnema/archup/internal/domain/user"
7)
8
9// EncryptionType represents the disk encryption method
10type EncryptionType int
11
12const (
13	// EncryptionTypeNone means no encryption
14	EncryptionTypeNone EncryptionType = iota
15
16	// EncryptionTypeLUKS means LUKS encryption (basic)
17	EncryptionTypeLUKS
18
19	// EncryptionTypeLUKSLVM means LUKS with LVM
20	EncryptionTypeLUKSLVM
21)
22
23// String returns human-readable encryption type name
24func (e EncryptionType) String() string {
25	switch e {
26	case EncryptionTypeLUKS:
27		return "LUKS"
28	case EncryptionTypeLUKSLVM:
29		return "LUKS+LVM"
30	default:
31		return "None"
32	}
33}
34
35// IsEncrypted returns true if encryption is enabled
36func (e EncryptionType) IsEncrypted() bool {
37	return e != EncryptionTypeNone
38}
39
40// EncryptionConfig is an immutable value object representing encryption configuration
41type EncryptionConfig struct {
42	encType  EncryptionType
43	password string
44}
45
46// NewEncryptionConfig creates a new encryption configuration with validation
47func NewEncryptionConfig(encType EncryptionType, password string) (*EncryptionConfig, error) {
48	// If encryption is enabled, password is required
49	if encType.IsEncrypted() && password == "" {
50		return nil, errors.New("encryption password required when encryption is enabled")
51	}
52
53	// If encryption is disabled, password should be empty
54	if !encType.IsEncrypted() && password != "" {
55		return nil, errors.New("password cannot be set when encryption is disabled")
56	}
57
58	// Validate password strength if encryption is enabled
59	if encType.IsEncrypted() {
60		if err := validateEncryptionPassword(password); err != nil {
61			return nil, err
62		}
63	}
64
65	return &EncryptionConfig{
66		encType:  encType,
67		password: password,
68	}, nil
69}
70
71// EncryptionType returns the encryption type
72func (e *EncryptionConfig) EncryptionType() EncryptionType {
73	return e.encType
74}
75
76// IsEncrypted returns true if encryption is enabled
77func (e *EncryptionConfig) IsEncrypted() bool {
78	return e.encType.IsEncrypted()
79}
80
81// HasPassword returns true if a password is set
82// (always true if encrypted, always false if not)
83func (e *EncryptionConfig) HasPassword() bool {
84	return e.password != ""
85}
86
87// String returns human-readable representation
88func (e *EncryptionConfig) String() string {
89	return "EncryptionConfig(type=" + e.encType.String() + ", encrypted=" + boolToString(e.IsEncrypted()) + ")"
90}
91
92// Equals checks if two EncryptionConfig objects are equal
93// Note: Password comparison is constant-time safe
94func (e *EncryptionConfig) Equals(other *EncryptionConfig) bool {
95	if other == nil {
96		return false
97	}
98	return e.encType == other.encType && constantTimeEqual(e.password, other.password)
99}
100
101// Private helper functions
102
103func validateEncryptionPassword(password string) error {
104	// Delegate to user password validation (single source of truth)
105	return user.ValidatePassword(password)
106}
107
108// constantTimeEqual compares two strings in constant time to prevent timing attacks
109func constantTimeEqual(a, b string) bool {
110	if len(a) != len(b) {
111		return false
112	}
113
114	result := 0
115	for i := 0; i < len(a); i++ {
116		result |= int(a[i]) ^ int(b[i])
117	}
118
119	return result == 0
120}
121
122func boolToString(b bool) string {
123	if b {
124		return "true"
125	}
126	return "false"
127}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close