use super::paths::Backend;
use crate::context::Context;
use crate::host::{Administered, Os};
use std::path::{Path, PathBuf};
const PREFERENCES: &str = "com.openai.codex";
const CONFIG_KEY: &str = "config_toml_base64";
const REQUIREMENTS_KEY: &str = "requirements_toml_base64";
const STORE: &str = "cli_auth_credentials_store";
const SECRETS: &str = "secret_auth_storage";
pub(crate) const FILE_STORE: &str = "cli_auth_credentials_store=\"file\"";
const PACKAGED: &str = "cli_auth_credentials_store = \"file\"\n";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum Layer {
Packaged,
System,
Own,
CommandLine,
Managed,
ManagedPreference,
Required,
RequiredByPreference,
}
impl Layer {
fn pins(self) -> bool {
matches!(self, Layer::Required | Layer::RequiredByPreference)
}
fn read_on(self, os: Os) -> bool {
match self {
Layer::System | Layer::Managed | Layer::Required => system_dir(os).is_some(),
Layer::Packaged
| Layer::Own
| Layer::CommandLine
| Layer::ManagedPreference
| Layer::RequiredByPreference => true,
}
}
fn place(self, os: Os, own: &Path) -> String {
let file = |name: &str| match system_dir(os) {
Some(dir) => dir.join(name).display().to_string(),
None => format!("Codex's own {name} for this machine"),
};
match self {
Layer::Packaged => "Codex's default".into(),
Layer::System => file("config.toml"),
Layer::Own => own.display().to_string(),
Layer::CommandLine => "the `-c` Pitboard's sign-ins give `codex login`".into(),
Layer::Managed => file("managed_config.toml"),
Layer::ManagedPreference => {
format!("the managed preference `{CONFIG_KEY}` of `{PREFERENCES}`")
}
Layer::Required => file("requirements.toml"),
Layer::RequiredByPreference => {
format!("the managed preference `{REQUIREMENTS_KEY}` of `{PREFERENCES}`")
}
}
}
}
fn system_dir(os: Os) -> Option<&'static Path> {
match os {
Os::MacOs | Os::Linux => Some(Path::new("/etc/codex")),
Os::Windows => None,
}
}
pub(crate) fn config_layers(os: Os) -> &'static [Layer] {
use Layer::{CommandLine, Managed, ManagedPreference, Own, Packaged, System};
match os {
Os::MacOs => &[
Packaged,
System,
Own,
CommandLine,
Managed,
ManagedPreference,
],
Os::Linux => &[Packaged, System, Own, CommandLine, Managed],
Os::Windows => &[Packaged, System, Own, CommandLine],
}
}
pub(crate) fn requirement_layers(os: Os) -> &'static [Layer] {
match os {
Os::MacOs => &[Layer::Required, Layer::RequiredByPreference],
Os::Linux | Os::Windows => &[Layer::Required],
}
}
fn secrets_by_default(os: Os) -> bool {
match os {
Os::MacOs | Os::Linux => false,
Os::Windows => true,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Mode {
File,
Keyring,
Auto,
Ephemeral,
}
impl Mode {
fn named(word: &str) -> Option<Mode> {
Some(match word {
"file" => Mode::File,
"keyring" => Mode::Keyring,
"auto" => Mode::Auto,
"ephemeral" => Mode::Ephemeral,
_ => return None,
})
}
fn word(self) -> &'static str {
match self {
Mode::File => "file",
Mode::Keyring => "keyring",
Mode::Auto => "auto",
Mode::Ephemeral => "ephemeral",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Store {
pub(crate) backend: Backend,
pub(crate) chosen_by: Layer,
mode: Mode,
secrets_by: Option<Layer>,
unknown: Option<Unknown>,
os: Os,
own: PathBuf,
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct Unknown {
layer: Layer,
why: String,
then: Then,
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum Then {
Stops,
NoProfile(String),
Unread,
}
impl Store {
pub(crate) fn setting(&self) -> String {
let place = self.place(self.chosen_by);
let mut said = match self.chosen_by {
Layer::Packaged => place,
layer if layer.pins() => format!("pinned to `{}` by {place}", self.mode.word()),
_ => format!("`{STORE} = \"{}\"` in {place}", self.mode.word()),
};
if self.backend == Backend::Secrets {
match self.secrets_by {
Some(layer) => {
said.push_str(&format!(", with `{SECRETS}` in {}", self.place(layer)))
}
None => said.push_str(&format!(", with `{SECRETS}` on by default")),
}
}
said
}
pub(crate) fn to_use_the_file(&self) -> String {
let line = format!("`{STORE} = \"file\"`");
let place = self.place(self.chosen_by);
match self.chosen_by {
Layer::Packaged | Layer::System | Layer::Own | Layer::CommandLine => format!(
"To use the file store, set {line} in {}, then sign in again with `codex login`",
self.own.display()
),
Layer::Managed => format!(
"{place} sets it over your own config.toml, so only an administrator can \
change it there to {line}"
),
Layer::ManagedPreference => format!(
"An administrator's configuration profile sets it in {place}, over every \
file, so only they can change it to {line}"
),
Layer::Required | Layer::RequiredByPreference => format!(
"No line in your own config.toml can change it: {place} pins it, and only \
an administrator can change that"
),
}
}
pub(crate) fn why_unknown(&self) -> Option<String> {
self.unknown.as_ref().map(|unknown| match unknown.then {
Then::Unread => {
"Pitboard does not read Codex's configuration on this system yet".into()
}
Then::Stops | Then::NoProfile(_) => {
format!("{} {}", self.place(unknown.layer), unknown.why)
}
})
}
pub(crate) fn while_unknown(&self) -> Option<String> {
self.unknown.as_ref().map(|unknown| match &unknown.then {
Then::Stops => "Codex 0.160.0 does not start until that is put right".into(),
Then::Unread => "This says nothing about Codex itself".into(),
Then::NoProfile(name) => format!(
"Codex 0.160.0 does not start with that line, and an older Codex, such as \
0.99.0, which chooses a profile with it, refuses one no table defines: \
\"config profile `{name}` not found\""
),
})
}
fn place(&self, layer: Layer) -> String {
layer.place(self.os, &self.own)
}
}
pub(crate) fn of(ctx: &Context, own: &Path) -> Store {
resolve(crate::host::OS, own, &|layer| {
read(ctx, layer, Some(own), None)
})
}
pub(crate) fn of_a_sign_in(ctx: &Context, own: &Path) -> Store {
resolve(crate::host::OS, own, &|layer| {
read(ctx, layer, None, Some(FILE_STORE))
})
}
fn read(
ctx: &Context,
layer: Layer,
own: Option<&Path>,
command_line: Option<&str>,
) -> Administered {
let host = ctx.host();
let file = |name: &str| match system_dir(crate::host::OS) {
Some(dir) => host.administered_file(&dir.join(name)),
None => Administered::Unreadable("is not read on this system yet".into()),
};
match layer {
Layer::Packaged => Administered::Set(PACKAGED.into()),
Layer::System => file("config.toml"),
Layer::Own => own.map_or(Administered::Unset, crate::host::administered::read_text),
Layer::CommandLine => command_line.map_or(Administered::Unset, |said| {
Administered::Set(said.to_string())
}),
Layer::Managed => file("managed_config.toml"),
Layer::ManagedPreference => decoded(host.managed_preference(PREFERENCES, CONFIG_KEY)),
Layer::Required => file("requirements.toml"),
Layer::RequiredByPreference => {
decoded(host.managed_preference(PREFERENCES, REQUIREMENTS_KEY))
}
}
}
fn decoded(forced: Administered) -> Administered {
match forced {
Administered::Set(encoded) => match standard_base64(encoded.trim()) {
None => Administered::Unreadable("is not base64".into()),
Some(bytes) => String::from_utf8(bytes).map_or_else(
|_| Administered::Unreadable("does not decode to UTF-8 text".into()),
Administered::Set,
),
},
other => other,
}
}
enum Says {
Nothing,
Table(toml::Table),
Broken(String),
Unread,
}
impl Says {
fn of(read: Administered) -> Says {
match read {
Administered::Unset => Says::Nothing,
Administered::Unreadable(why) => Says::Broken(why),
Administered::Set(text) => match text.parse::<toml::Table>() {
Ok(table) => Says::Table(table),
Err(e) => Says::Broken(match e.span() {
Some(at) => format!(
"is not TOML Codex can read, at line {}",
text.bytes().take(at.start).filter(|&b| b == b'\n').count() + 1
),
None => "is not TOML Codex can read".into(),
}),
},
}
}
fn table(&self) -> Option<&toml::Table> {
match self {
Says::Table(table) => Some(table),
Says::Nothing | Says::Broken(_) | Says::Unread => None,
}
}
}
enum Set<T> {
Unset,
To(T),
Refused(String),
}
fn store_in(table: &toml::Table) -> Set<Mode> {
match table.get(STORE) {
None => Set::Unset,
Some(toml::Value::String(word)) => {
Mode::named(word).map_or_else(|| not_a_store(&format!("`\"{word}\"`")), Set::To)
}
Some(other) => not_a_store(&kind(other)),
}
}
fn not_a_store<T>(written: &str) -> Set<T> {
Set::Refused(format!(
"{STORE} to {written}, which is not a store Codex has"
))
}
fn kind(value: &toml::Value) -> String {
let name = value.type_str();
let article = if name.starts_with(['a', 'e', 'i', 'o', 'u']) {
"an"
} else {
"a"
};
format!("{article} {name}")
}
fn profile_in(table: &toml::Table) -> Set<String> {
match table.get("profile") {
None => Set::Unset,
Some(toml::Value::String(name)) => Set::To(name.clone()),
Some(other) => Set::Refused(format!(
"`profile` to {}, where Codex takes a profile's name",
kind(other)
)),
}
}
fn profile_table_in(table: &toml::Table, name: &str) -> Set<()> {
let not_a_table = |key: &str, value: &toml::Value| {
Set::Refused(format!(
"`{key}` to {}, where Codex takes a table",
kind(value)
))
};
match table.get("profiles") {
None => Set::Unset,
Some(toml::Value::Table(profiles)) => match profiles.get(name) {
None => Set::Unset,
Some(toml::Value::Table(_)) => Set::To(()),
Some(other) => not_a_table(&format!("profiles.{name}"), other),
},
Some(other) => not_a_table("profiles", other),
}
}
#[derive(Debug, Clone, Copy)]
enum Features {
OfConfiguration,
OfRequirement,
}
fn secrets_in(table: &toml::Table, of: Features) -> Set<bool> {
let features = table.get("features").or_else(|| match of {
Features::OfRequirement => table.get("feature_requirements"),
Features::OfConfiguration => None,
});
match features {
None => Set::Unset,
Some(toml::Value::Table(features)) => match features.get(SECRETS) {
None => Set::Unset,
Some(toml::Value::Boolean(on)) => Set::To(*on),
Some(other) => Set::Refused(format!(
"`{SECRETS}` to {}, where Codex takes only true or false",
kind(other)
)),
},
Some(other) => Set::Refused(format!(
"`features` to {}, where Codex takes a table",
kind(other)
)),
}
}
fn highest<'a, T>(
layers: impl DoubleEndedIterator<Item = &'a (Layer, Says)>,
get: impl Fn(&toml::Table) -> Set<T>,
) -> Option<(Layer, Result<T, String>)> {
layers
.rev()
.find_map(|(layer, says)| match get(says.table()?) {
Set::Unset => None,
Set::To(value) => Some((*layer, Ok(value))),
Set::Refused(written) => Some((*layer, Err(written))),
})
}
pub(crate) fn resolve(os: Os, own: &Path, read: &dyn Fn(Layer) -> Administered) -> Store {
let read_all = |layers: &[Layer]| -> Vec<(Layer, Says)> {
layers
.iter()
.map(|&layer| {
let says = if layer.read_on(os) {
Says::of(read(layer))
} else {
Says::Unread
};
(layer, says)
})
.collect()
};
let (required, config) = (
read_all(requirement_layers(os)),
read_all(config_layers(os)),
);
let store = |backend, chosen_by, mode, secrets_by, unknown| Store {
backend,
chosen_by,
mode,
secrets_by,
unknown,
os,
own: own.to_path_buf(),
};
let unknown = |layer: Layer, why: String, then: Then| {
store(
Backend::Unknown,
layer,
Mode::File,
None,
Some(Unknown { layer, why, then }),
)
};
if let Some((layer, why, then)) =
required
.iter()
.rev()
.chain(config.iter().rev())
.find_map(|(layer, says)| match says {
Says::Broken(why) => Some((*layer, why.clone(), Then::Stops)),
Says::Unread => Some((*layer, String::new(), Then::Unread)),
Says::Nothing | Says::Table(_) => None,
})
{
return unknown(layer, why, then);
}
let refused = |layer, wrong: String| unknown(layer, format!("sets {wrong}"), Then::Stops);
let configured = match highest(config.iter(), store_in) {
Some((layer, Ok(mode))) => (layer, mode),
Some((layer, Err(wrong))) => return refused(layer, wrong),
None => (Layer::Packaged, Mode::File),
};
let (chosen_by, mode) = match highest(required.iter(), store_in) {
Some((layer, Ok(mode))) => (layer, mode),
Some((layer, Err(wrong))) => return refused(layer, wrong),
None => configured,
};
let configured_secrets = match highest(config.iter(), |table| {
secrets_in(table, Features::OfConfiguration)
}) {
Some((layer, Ok(on))) => Some((layer, on)),
Some((layer, Err(wrong))) => return refused(layer, wrong),
None => None,
};
let (secrets_by, secrets) = match highest(required.iter(), |table| {
secrets_in(table, Features::OfRequirement)
}) {
Some((layer, Ok(on))) => (Some(layer), on),
Some((layer, Err(wrong))) => return refused(layer, wrong),
None => configured_secrets.map_or((None, secrets_by_default(os)), |(layer, on)| {
(Some(layer), on)
}),
};
match highest(config.iter(), profile_in) {
Some((layer, Ok(name))) => {
match highest(config.iter(), |table| profile_table_in(table, &name)) {
Some((_, Ok(()))) => {}
Some((defined, Err(wrong))) => return refused(defined, wrong),
None => {
return unknown(
layer,
format!(
"sets `profile = \"{name}\"`, a profile no `[profiles.{name}]` \
table defines"
),
Then::NoProfile(name),
);
}
}
}
Some((layer, Err(wrong))) => return refused(layer, wrong),
None => {}
}
let backend = match mode {
Mode::File => Backend::File,
Mode::Ephemeral => Backend::Ephemeral,
Mode::Keyring | Mode::Auto if secrets => Backend::Secrets,
Mode::Keyring => Backend::Keyring,
Mode::Auto => Backend::Either,
};
let secrets_by = secrets_by.filter(|_| backend == Backend::Secrets);
store(backend, chosen_by, mode, secrets_by, None)
}
fn standard_base64(text: &str) -> Option<Vec<u8>> {
let bytes = text.as_bytes();
if !bytes.len().is_multiple_of(4) {
return None;
}
let padding = bytes.iter().rev().take_while(|&&b| b == b'=').count();
if padding > 2 {
return None;
}
let mut out = Vec::with_capacity(bytes.len() / 4 * 3);
let (mut held, mut bits) = (0u32, 0);
for &byte in &bytes[..bytes.len() - padding] {
let sextet = match byte {
b'A'..=b'Z' => byte - b'A',
b'a'..=b'z' => byte - b'a' + 26,
b'0'..=b'9' => byte - b'0' + 52,
b'+' => 62,
b'/' => 63,
_ => return None,
};
held = (held << 6) | u32::from(sextet);
bits += 6;
if bits >= 8 {
bits -= 8;
out.push(u8::try_from((held >> bits) & 0xff).expect("masked to one byte"));
}
}
((held & ((1u32 << bits) - 1)) == 0).then_some(out)
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
const OWN: &str = "/Users/someone/.codex/config.toml";
fn machine(os: Os, holds: &[(Layer, &str)]) -> Store {
let holds: HashMap<Layer, Administered> = holds
.iter()
.map(|&(layer, text)| {
let forced = Administered::Set(text.to_string());
let holds = match layer {
Layer::ManagedPreference | Layer::RequiredByPreference => decoded(forced),
_ => forced,
};
(layer, holds)
})
.collect();
resolve(os, Path::new(OWN), &|layer| match layer {
Layer::Packaged => Administered::Set(PACKAGED.into()),
_ => holds.get(&layer).cloned().unwrap_or(Administered::Unset),
})
}
const KEYRING: &str = "cli_auth_credentials_store = \"keyring\"\n";
const FILE: &str = "cli_auth_credentials_store = \"file\"\n";
const EPHEMERAL: &str = "cli_auth_credentials_store = \"ephemeral\"\n";
fn base64(text: &str) -> String {
const ALPHABET: &[u8; 64] =
b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut out = String::new();
for chunk in text.as_bytes().chunks(3) {
let n = chunk
.iter()
.enumerate()
.fold(0u32, |n, (i, &b)| n | (u32::from(b) << (16 - 8 * i)));
for i in 0..4 {
if i <= chunk.len() {
out.push(char::from(ALPHABET[((n >> (18 - 6 * i)) & 63) as usize]));
} else {
out.push('=');
}
}
}
out
}
#[test]
fn nothing_set_is_codex_default_the_file() {
for os in [Os::MacOs, Os::Linux] {
let store = machine(os, &[]);
assert_eq!(store.backend, Backend::File);
assert_eq!(store.chosen_by, Layer::Packaged);
assert_eq!(store.setting(), "Codex's default");
}
}
#[test]
fn a_higher_layer_replaces_a_lower_one() {
for os in [Os::MacOs, Os::Linux] {
let store = machine(os, &[(Layer::System, KEYRING)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::System)
);
let store = machine(os, &[(Layer::System, KEYRING), (Layer::Own, FILE)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::Own),
"the person's own config.toml is over the system's"
);
let store = machine(os, &[(Layer::Own, FILE), (Layer::Managed, KEYRING)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Managed),
"managed_config.toml is over the person's"
);
let store = machine(
os,
&[(Layer::Own, KEYRING), (Layer::CommandLine, FILE_STORE)],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::CommandLine),
"a -c is over the person's config.toml"
);
let store = machine(
os,
&[(Layer::Managed, KEYRING), (Layer::CommandLine, FILE_STORE)],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Managed),
"and under managed_config.toml"
);
}
}
#[test]
fn managed_preferences_are_read_on_macos_alone() {
let forced = base64(KEYRING);
let broken = format!("{}\n{}", &forced[..4], &forced[4..]);
let holds = [
(Layer::Managed, FILE),
(Layer::ManagedPreference, forced.as_str()),
];
let store = machine(Os::MacOs, &holds);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::ManagedPreference)
);
assert_eq!(machine(Os::Linux, &holds).backend, Backend::File);
let holds = [
(Layer::Own, KEYRING),
(Layer::Required, KEYRING),
(Layer::RequiredByPreference, broken.as_str()),
];
assert_eq!(
machine(Os::MacOs, &holds).backend,
Backend::Unknown,
"a forced value that is not canonical base64 is one Codex cannot read"
);
let file = base64(FILE);
let holds = [
(Layer::Own, KEYRING),
(Layer::Required, KEYRING),
(Layer::RequiredByPreference, file.as_str()),
];
let store = machine(Os::MacOs, &holds);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::RequiredByPreference)
);
let store = machine(Os::Linux, &holds);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Required)
);
}
#[test]
fn a_requirement_pins_the_store_over_every_layer() {
let forced = base64(FILE);
let store = machine(
Os::MacOs,
&[
(Layer::Own, FILE),
(Layer::CommandLine, FILE_STORE),
(Layer::Managed, FILE),
(Layer::ManagedPreference, forced.as_str()),
(Layer::Required, EPHEMERAL),
],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Ephemeral, Layer::Required)
);
assert_eq!(
store.setting(),
"pinned to `ephemeral` by /etc/codex/requirements.toml"
);
assert_eq!(
store.to_use_the_file(),
"No line in your own config.toml can change it: /etc/codex/requirements.toml \
pins it, and only an administrator can change that"
);
}
#[test]
fn a_setting_of_the_persons_own_names_the_line_and_the_file() {
let store = machine(
Os::Linux,
&[(Layer::System, "cli_auth_credentials_store = 'auto'")],
);
assert_eq!(store.backend, Backend::Either);
assert_eq!(
store.setting(),
"`cli_auth_credentials_store = \"auto\"` in /etc/codex/config.toml"
);
assert_eq!(
store.to_use_the_file(),
format!(
"To use the file store, set `cli_auth_credentials_store = \"file\"` in {OWN}, \
then sign in again with `codex login`"
)
);
let store = machine(Os::Linux, &[(Layer::Managed, KEYRING)]);
assert_eq!(
store.to_use_the_file(),
"/etc/codex/managed_config.toml sets it over your own config.toml, so only an \
administrator can change it there to `cli_auth_credentials_store = \"file\"`"
);
}
#[test]
fn the_secret_store_is_read_from_the_same_layers() {
let on = "[features]\nsecret_auth_storage = true\n";
let off = "[features]\nsecret_auth_storage = false\n";
for os in [Os::MacOs, Os::Linux] {
assert_eq!(
machine(os, &[(Layer::Own, KEYRING)]).backend,
Backend::Keyring
);
let store = machine(os, &[(Layer::Own, KEYRING), (Layer::System, on)]);
assert_eq!(store.backend, Backend::Secrets);
assert_eq!(
store.setting(),
format!(
"`cli_auth_credentials_store = \"keyring\"` in {OWN}, with \
`secret_auth_storage` in /etc/codex/config.toml"
)
);
assert_eq!(
machine(
os,
&[
(Layer::Own, KEYRING),
(Layer::System, on),
(Layer::Managed, off)
]
)
.backend,
Backend::Keyring
);
assert_eq!(
machine(
os,
&[
(Layer::Own, KEYRING),
(Layer::Managed, off),
(
Layer::Required,
"[feature_requirements]\nsecret_auth_storage = true\n"
)
]
)
.backend,
Backend::Secrets,
"a requirement pins a feature too, under either name of its table"
);
assert_eq!(
machine(
os,
&[
(Layer::Own, KEYRING),
(
Layer::System,
"[feature_requirements]\nsecret_auth_storage = true\n"
)
]
)
.backend,
Backend::Keyring,
"only a requirement's table has that second name"
);
assert_eq!(
machine(
os,
&[
(Layer::Own, KEYRING),
(Layer::Managed, "feature_requirements = 1\n")
]
)
.backend,
Backend::Keyring,
"and a configuration layer's table of that name sets nothing"
);
assert_eq!(machine(os, &[(Layer::Own, on)]).backend, Backend::File);
}
}
#[test]
fn an_administrator_who_chooses_the_file_is_over_the_persons_own_store() {
let forced = base64(FILE);
for (own, alone) in [
(KEYRING, Backend::Keyring),
("cli_auth_credentials_store = \"auto\"\n", Backend::Either),
(EPHEMERAL, Backend::Ephemeral),
] {
for os in [Os::Linux, Os::MacOs] {
assert_eq!(machine(os, &[(Layer::Own, own)]).backend, alone);
for layer in [Layer::Managed, Layer::Required] {
let store = machine(os, &[(Layer::Own, own), (layer, FILE)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, layer),
"{os:?}: {layer:?} over {alone:?}"
);
}
}
for layer in [Layer::ManagedPreference, Layer::RequiredByPreference] {
let holds = [(Layer::Own, own), (layer, forced.as_str())];
assert_eq!(
(
machine(Os::MacOs, &holds).backend,
machine(Os::Linux, &holds).backend
),
(Backend::File, alone),
"{layer:?} over {alone:?}, which Linux does not read"
);
}
}
assert_eq!(
machine(Os::Linux, &[(Layer::Own, KEYRING), (Layer::System, FILE)]).backend,
Backend::Keyring,
"/etc/codex/config.toml is under the person's own, so it lifts nothing"
);
}
#[test]
fn a_layer_codex_cannot_read_is_unknown_never_the_file() {
for (layer, text, why) in [
(
Layer::System,
"cli_auth_credentials_store = \n",
"is not TOML Codex can read, at line 1",
),
(
Layer::Own,
"model = \"o3\"\n[[[\n",
"is not TOML Codex can read, at line 2",
),
(
Layer::Required,
"]",
"is not TOML Codex can read, at line 1",
),
(
Layer::Own,
"cli_auth_credentials_store = \"nonsense\"\n",
"sets cli_auth_credentials_store to `\"nonsense\"`, which is not a store Codex has",
),
(
Layer::Managed,
"cli_auth_credentials_store = 1\n",
"sets cli_auth_credentials_store to an integer, which is not a store Codex has",
),
(
Layer::System,
"[features]\nsecret_auth_storage = \"yes\"\n",
"sets `secret_auth_storage` to a string, where Codex takes only true or false",
),
] {
let store = machine(Os::Linux, &[(Layer::Own, FILE), (layer, text)]);
assert_eq!(store.backend, Backend::Unknown, "{text}");
assert_eq!(
store.why_unknown(),
Some(format!("{} {why}", layer.place(Os::Linux, Path::new(OWN)))),
"{text}"
);
}
let unreadable = resolve(Os::Linux, Path::new(OWN), &|layer| match layer {
Layer::Packaged => Administered::Set(PACKAGED.into()),
Layer::Required => Administered::Unreadable("cannot be read: denied".into()),
_ => Administered::Unset,
});
assert_eq!(unreadable.backend, Backend::Unknown);
assert_eq!(
unreadable.why_unknown().as_deref(),
Some("/etc/codex/requirements.toml cannot be read: denied")
);
}
const PROFILED: &str = "profile = \"work\"\n[profiles.work]\nmodel = \"o3\"\n";
#[test]
fn a_profile_line_chooses_its_profile_and_the_store_is_still_the_layers() {
let chosen_over_a_file = format!("profile = \"work\"\n{FILE}");
for os in [Os::MacOs, Os::Linux] {
for layer in [Layer::System, Layer::Own, Layer::Managed] {
let store = machine(os, &[(layer, PROFILED)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::Packaged),
"{os:?}: {layer:?}"
);
assert_eq!(store.setting(), "Codex's default");
assert_eq!(store.why_unknown(), None);
}
let store = machine(
os,
&[
(Layer::System, "[profiles.work]\nmodel = \"o3\"\n"),
(Layer::Own, chosen_over_a_file.as_str()),
],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::Own),
"{os:?}: a profile one layer defines and another chooses"
);
}
}
#[test]
fn a_chosen_profiles_table_holds_no_store_codex_reads() {
for os in [Os::MacOs, Os::Linux] {
let keychain_in_profile = "profile = \"work\"\n[profiles.work]\n\
cli_auth_credentials_store = \"keyring\"\n\
[profiles.work.features]\nsecret_auth_storage = true\n";
let store = machine(os, &[(Layer::Own, keychain_in_profile)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::Packaged),
"{os:?}"
);
let nonsense_in_profile = "profile = \"work\"\n[profiles.work]\n\
cli_auth_credentials_store = \"nonsense\"\n";
assert_eq!(
machine(os, &[(Layer::Own, nonsense_in_profile)]).backend,
Backend::File,
"{os:?}: a key Codex drops stops nothing"
);
let file_in_profile = "cli_auth_credentials_store = \"keyring\"\nprofile = \"work\"\n\
[profiles.work]\ncli_auth_credentials_store = \"file\"\n";
let store = machine(os, &[(Layer::Own, file_in_profile)]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Own),
"{os:?}"
);
assert_eq!(
store.setting(),
format!("`cli_auth_credentials_store = \"keyring\"` in {OWN}")
);
assert_eq!(
store.to_use_the_file(),
format!(
"To use the file store, set `cli_auth_credentials_store = \"file\"` in \
{OWN}, then sign in again with `codex login`"
)
);
let tables_alone = "[profiles.work]\ncli_auth_credentials_store = \"keyring\"\n";
assert_eq!(
machine(os, &[(Layer::Own, tables_alone)]).backend,
Backend::File,
"{os:?}: a profile's table that nothing chooses changes nothing"
);
}
}
#[test]
fn a_chosen_profile_leaves_a_store_that_is_not_the_file_to_be_refused_as_itself() {
let keyring_chosen = format!("profile = \"work\"\n{KEYRING}[profiles.work]\n");
let store = machine(Os::Linux, &[(Layer::Own, keyring_chosen.as_str())]);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Own)
);
let store = machine(
Os::Linux,
&[(Layer::Own, PROFILED), (Layer::Managed, EPHEMERAL)],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Ephemeral, Layer::Managed)
);
let store = machine(
Os::MacOs,
&[(Layer::Own, PROFILED), (Layer::Required, KEYRING)],
);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Keyring, Layer::Required)
);
assert_eq!(
store.setting(),
"pinned to `keyring` by /etc/codex/requirements.toml"
);
}
#[test]
fn a_profile_no_table_defines_is_unknown_never_the_file() {
for (layer, holds) in [
(Layer::Own, vec![(Layer::Own, "profile = \"work\"\n")]),
(
Layer::System,
vec![
(
Layer::System,
"profile = \"work\"\n[profiles.home]\nmodel = \"o3\"\n",
),
(Layer::Own, FILE),
],
),
(
Layer::Managed,
vec![
(Layer::Managed, "profile = \"work\"\n"),
(Layer::Own, "[profiles.home]\nmodel = \"o3\"\n"),
],
),
] {
let store = machine(Os::Linux, &holds);
assert_eq!(store.backend, Backend::Unknown, "{layer:?}");
assert_eq!(
store.why_unknown(),
Some(format!(
"{} sets `profile = \"work\"`, a profile no `[profiles.work]` table defines",
layer.place(Os::Linux, Path::new(OWN))
)),
"{layer:?}"
);
assert_eq!(
store.while_unknown().as_deref(),
Some(
"Codex 0.160.0 does not start with that line, and an older Codex, such as \
0.99.0, which chooses a profile with it, refuses one no table defines: \
\"config profile `work` not found\""
),
"{layer:?}"
);
}
}
#[test]
fn a_profile_codex_cannot_read_stops_it_as_any_value_it_cannot_take() {
for (text, why) in [
(
"profile = 3\n",
"sets `profile` to an integer, where Codex takes a profile's name",
),
(
"profile = \"work\"\nprofiles = 3\n",
"sets `profiles` to an integer, where Codex takes a table",
),
(
"profile = \"work\"\n[profiles]\nwork = \"o3\"\n",
"sets `profiles.work` to a string, where Codex takes a table",
),
(
"profile = \"work\"\ncli_auth_credentials_store = \"nonsense\"\n",
"sets cli_auth_credentials_store to `\"nonsense\"`, which is not a store \
Codex has",
),
] {
let store = machine(Os::Linux, &[(Layer::Own, text)]);
assert_eq!(store.backend, Backend::Unknown, "{text}");
assert_eq!(store.why_unknown(), Some(format!("{OWN} {why}")), "{text}");
assert_eq!(
store.while_unknown().as_deref(),
Some("Codex 0.160.0 does not start until that is put right"),
"{text}"
);
}
}
#[test]
fn a_value_codex_cannot_take_is_replaced_by_a_higher_one() {
let store = machine(
Os::Linux,
&[
(Layer::System, "cli_auth_credentials_store = \"nonsense\"\n"),
(Layer::Own, FILE),
],
);
assert_eq!(store.backend, Backend::File);
}
#[test]
fn a_sign_in_takes_the_file_store_unless_an_administrator_set_another() {
let host = crate::host::memory::MemoryHost::new();
let ctx = Context::for_unit_test().with_memory_stores(host.clone());
let own = Path::new(OWN);
assert_eq!(of_a_sign_in(&ctx, own).backend, Backend::File);
host.administers("/etc/codex/config.toml", KEYRING);
let store = of_a_sign_in(&ctx, own);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::File, Layer::CommandLine),
"the -c is over the system's config"
);
host.administers("/etc/codex/managed_config.toml", KEYRING);
assert_eq!(of_a_sign_in(&ctx, own).backend, Backend::Keyring);
host.administers("/etc/codex/managed_config.toml", FILE);
host.administers("/etc/codex/requirements.toml", EPHEMERAL);
let store = of_a_sign_in(&ctx, own);
assert_eq!(
(store.backend, store.chosen_by),
(Backend::Ephemeral, Layer::Required)
);
}
#[test]
fn what_an_administrator_set_is_read_through_the_host() {
let host = crate::host::memory::MemoryHost::new();
let ctx = Context::for_unit_test().with_memory_stores(host.clone());
let own = Path::new(OWN);
assert_eq!(of(&ctx, own).chosen_by, Layer::Packaged);
host.administers("/etc/codex/requirements.toml", KEYRING);
assert_eq!(of(&ctx, own).chosen_by, Layer::Required);
host.administers_unreadably("/etc/codex/config.toml", "cannot be read: denied");
assert_eq!(of(&ctx, own).backend, Backend::Unknown);
let host = crate::host::memory::MemoryHost::new();
let ctx = Context::for_unit_test().with_memory_stores(host.clone());
host.forces(
PREFERENCES,
CONFIG_KEY,
&format!(" {}\n", base64(EPHEMERAL)),
);
let store = of(&ctx, own);
match crate::host::OS {
Os::MacOs => assert_eq!(
(store.backend, store.chosen_by),
(Backend::Ephemeral, Layer::ManagedPreference)
),
Os::Linux => assert_eq!(store.backend, Backend::File),
Os::Windows => assert_eq!(store.backend, Backend::Unknown),
}
}
#[test]
fn on_windows_the_store_is_one_nobody_can_tell_whatever_the_layers_say() {
for holds in [
&[][..],
&[(Layer::Own, FILE)],
&[(Layer::Own, KEYRING)],
&[(Layer::Own, FILE), (Layer::CommandLine, FILE_STORE)],
&[(Layer::System, KEYRING), (Layer::Required, FILE)],
] {
let store = machine(Os::Windows, holds);
assert_eq!(store.backend, Backend::Unknown, "{holds:?}");
assert_eq!(
store.why_unknown().as_deref(),
Some("Pitboard does not read Codex's configuration on this system yet"),
"{holds:?}"
);
assert_eq!(
store.while_unknown().as_deref(),
Some("This says nothing about Codex itself"),
"{holds:?}"
);
}
let host = crate::host::memory::MemoryHost::new();
let ctx = Context::for_unit_test().with_memory_stores(host);
let signing_in = resolve(Os::Windows, Path::new(OWN), &|layer| {
read(&ctx, layer, None, Some(FILE_STORE))
});
assert_eq!(signing_in.backend, Backend::Unknown, "a sign-in's too");
}
#[test]
fn base64_is_read_as_codex_reads_it() {
for text in ["", "f", "fo", "foo", "foob", "fooba", "foobar"] {
assert_eq!(
standard_base64(&base64(text)),
Some(text.as_bytes().to_vec()),
"{text}"
);
}
assert_eq!(standard_base64("+/+/"), Some(vec![0xfb, 0xff, 0xbf]));
for refused in [
"Zg", "Zg=", "Zm9v=", "Zh==", "Z===", "-_-_", "Zm 9v", "Zg==Zg==",
] {
assert_eq!(standard_base64(refused), None, "{refused}");
}
}
}