AQIT
0.1.0
Toggle main menu visibility
Loading...
Searching...
No Matches
license_acceptance.py
Go to the documentation of this file.
1
# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2
# This file is part of the Aquin Engine. Unauthorized copying, modification,
3
# distribution, or use of this file, via any medium, is strictly prohibited.
4
# Proprietary and confidential. See LICENSE for terms.
5
6
"""First-run AQIT license acceptance gate."""
7
8
from
__future__
import
annotations
9
10
import
hashlib
11
import
os
12
import
sys
13
from
datetime
import
datetime, timezone
14
from
typing
import
Any
15
16
from
aquin.auth_config
import
load_config, save_config
17
from
aquin.license_text
import
LICENSE_URL, read_license_text
18
19
# Only `aquin license` (read terms) bypasses the gate. Everything else requires acceptance.
20
_LICENSE_EXEMPT_CMDS = frozenset({
"license"
})
21
22
23
def
current_license_hash
() -> str:
24
return
hashlib.sha256(read_license_text().encode(
"utf-8"
)).hexdigest()
25
26
27
def
_accepted_record
(cfg: dict[str, Any]) -> dict[str, Any] |
None
:
28
block = cfg.get(
"license_accepted"
)
29
return
block
if
isinstance(block, dict)
else
None
30
31
32
def
is_license_accepted
() -> bool:
33
record =
_accepted_record
(load_config())
34
if
not
record:
35
return
False
36
return
str(record.get(
"hash"
)
or
""
).strip() ==
current_license_hash
()
37
38
39
def
record_license_acceptance
() -> None:
40
cfg = load_config()
41
cfg[
"license_accepted"
] = {
42
"hash"
:
current_license_hash
(),
43
"accepted_at"
: datetime.now(timezone.utc).isoformat(),
44
}
45
save_config(cfg)
46
47
48
def
_env_auto_accept
() -> bool:
49
return
os.environ.get(
"AQUIN_LICENSE_ACCEPTED"
,
""
).strip().lower()
in
{
"1"
,
"true"
,
"yes"
}
50
51
52
def
ensure_license_accepted
(*, cmd: str |
None
) ->
None
:
53
if
cmd
in
_LICENSE_EXEMPT_CMDS:
54
return
55
if
is_license_accepted
():
56
return
57
if
_env_auto_accept
():
58
record_license_acceptance
()
59
return
60
_prompt_and_accept
(context=
"first_use"
)
61
62
63
def
accept_license_cli
() -> None:
64
"""Non-interactive acceptance via `aquin --accept-license`."""
65
if
is_license_accepted
():
66
print(
"License already accepted."
)
67
return
68
record_license_acceptance
()
69
print(
"License accepted."
)
70
71
72
def
_non_tty_message
() -> None:
73
print(
74
"The AQIT license has not been accepted on this machine.\n"
75
"The CLI is unusable until you accept.\n"
76
f
"Read the license: {LICENSE_URL}\n"
77
"Or run: aqit license --plain\n"
78
"Then run any aqit command interactively and accept when prompted, or run:\n"
79
" aqit --accept-license\n"
80
"after reviewing the terms (non-interactive / CI: set AQUIN_LICENSE_ACCEPTED=1)."
,
81
file=sys.stderr,
82
)
83
84
85
def
_prompt_and_accept
(*, context: str =
"first_use"
, exit_on_decline: bool =
True
) -> bool:
86
if
not
sys.stdin.isatty():
87
_non_tty_message
()
88
if
exit_on_decline:
89
sys.exit(1)
90
return
False
91
92
from
aquin.license_display
import
prompt_license_acceptance
93
94
if
not
prompt_license_acceptance(context=context):
95
if
exit_on_decline:
96
print(
"License not accepted. The CLI is unusable until you accept."
)
97
sys.exit(1)
98
print(
"License not accepted. The CLI is unusable until you accept."
)
99
return
False
100
101
record_license_acceptance
()
102
from
aquin.ascii_layout
import
center, rule, width
103
104
print()
105
w = width()
106
print(rule(
"="
, w))
107
print(center(
"LICENSE ACCEPTED"
, w))
108
print(rule(
"="
, w))
109
print()
110
return
True
aquin.ascii_layout
Definition
ascii_layout.py:1
aquin.auth_config
Definition
auth_config.py:1
aquin.license_acceptance._env_auto_accept
bool _env_auto_accept()
Definition
license_acceptance.py:52
aquin.license_acceptance.current_license_hash
str current_license_hash()
Definition
license_acceptance.py:27
aquin.license_acceptance._accepted_record
dict[str, Any]|None _accepted_record(dict[str, Any] cfg)
Definition
license_acceptance.py:31
aquin.license_acceptance._prompt_and_accept
bool _prompt_and_accept(*, str context="first_use", bool exit_on_decline=True)
Definition
license_acceptance.py:89
aquin.license_acceptance.ensure_license_accepted
None ensure_license_accepted(*, str|None cmd)
Definition
license_acceptance.py:56
aquin.license_acceptance.accept_license_cli
None accept_license_cli()
Definition
license_acceptance.py:67
aquin.license_acceptance.record_license_acceptance
None record_license_acceptance()
Definition
license_acceptance.py:43
aquin.license_acceptance._non_tty_message
None _non_tty_message()
Definition
license_acceptance.py:76
aquin.license_acceptance.is_license_accepted
bool is_license_accepted()
Definition
license_acceptance.py:36
aquin.license_display
Definition
license_display.py:1
aquin.license_text
Definition
license_text.py:1
aquin
license_acceptance.py
AQIT · Aquin Labs Private Limited · Apache 2.0 · Generated by
1.18.0