Skip to content

Commit

Permalink
Refactored fxa-client
Browse files Browse the repository at this point in the history
This was part of my work for the auth PR, but I think it's useful
separatedly.

- Updated `fxa-client` to be a single binary.
- Added a cargo alias so it can be run with `cargo fxa [args]`.

I think this makes it easier to use and also will make it easier to
expand the functionality.  It's easier to add another clap subcommand
than to add a new binary.
  • Loading branch information
bendk committed Jun 27, 2023
1 parent 2bf9814 commit 6f74754
Show file tree
Hide file tree
Showing 8 changed files with 203 additions and 198 deletions.
1 change: 1 addition & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ regen-protobufs = ["run", "--bin", "protobuf-gen", "tools/protobuf_files.toml"]
uniffi-bindgen = ["run", "--package", "embedded-uniffi-bindgen", "--"]
dev-install = ["install", "asdev"]
verify_env = ["asdev", "verify_env"]
fxa = ["run", "-p", "examples-fxa-client", "--"]
27 changes: 1 addition & 26 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions components/fxa-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ pub use push::{
pub use token::{AccessTokenInfo, AuthorizationParameters, ScopedKey};

/// Result returned by internal functions
type Result<T> = std::result::Result<T, Error>;
pub type Result<T> = std::result::Result<T, Error>;
/// Result returned by public-facing API functions
type ApiResult<T> = std::result::Result<T, FxaError>;
pub type ApiResult<T> = std::result::Result<T, FxaError>;

/// Object representing the signed-in state of an application.
///
Expand Down
15 changes: 2 additions & 13 deletions examples/fxa-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,11 @@ license = "MPL-2.0"
edition = "2021"
publish = false

# These three all have the same deps, and not a ton of them, so just bundle them
# as 3 examples in 1 crate.

[[example]]
name = "fxa-devices-api"
path = "src/devices-api.rs"
[[example]]
name = "fxa-oauth-flow"
path = "src/oauth-flow.rs"

[dev-dependencies]
[dependencies]
viaduct-reqwest = { path = "../../components/support/viaduct-reqwest" }
clap = {version = "4.2", features = ["derive"]}
cli-support = { path = "../cli-support" }
fxa-client = { path = "../../components/fxa-client" }
anyhow = "1.0"
dialoguer = "0.10"
webbrowser = "0.5"
url = "2.2"
sync15 = { path = "../../components/sync15" }
157 changes: 0 additions & 157 deletions examples/fxa-client/src/devices-api.rs

This file was deleted.

41 changes: 41 additions & 0 deletions examples/fxa-client/src/devices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use clap::{Args, Subcommand};
use fxa_client::FirefoxAccount;

use crate::{persist_fxa_state, Result};

#[derive(Args)]
pub struct DeviceArgs {
#[command(subcommand)]
command: Option<Command>,
}

#[derive(Subcommand)]
enum Command {
List,
SetName { name: String },
}

pub fn run(account: &FirefoxAccount, args: DeviceArgs) -> Result<()> {
match args.command.unwrap_or(Command::List) {
Command::List => list(account),
Command::SetName { name } => set_name(account, name),
}
}

fn list(account: &FirefoxAccount) -> Result<()> {
for device in account.get_devices(false)? {
println!("{}: {}", device.id, device.display_name);
}
Ok(())
}

fn set_name(account: &FirefoxAccount, name: String) -> Result<()> {
account.set_device_name(&name)?;
println!("Display name set to {name}");
persist_fxa_state(account)?;
Ok(())
}
89 changes: 89 additions & 0 deletions examples/fxa-client/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

mod devices;
mod send_tab;

use std::fs;

use clap::{Parser, Subcommand, ValueEnum};
use cli_support::fxa_creds::get_cli_fxa;
use fxa_client::{FirefoxAccount, FxaConfig, FxaServer};

static CREDENTIALS_PATH: &str = "credentials.json";
static CLIENT_ID: &str = "a2270f727f45f648";
static REDIRECT_URI: &str = "https://accounts.firefox.com/oauth/success/a2270f727f45f648";

use anyhow::Result;

#[derive(Parser)]
#[command(about, long_about = None)]
struct Cli {
/// The FxA server to use
#[arg(value_enum, default_value_t = Server::Release)]
server: Server,

#[command(subcommand)]
command: Command,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum Server {
/// Official server
Release,
/// China server
China,
/// stable dev sever
Stable,
/// staging dev sever
Stage,
/// local dev sever
LocalDev,
}

#[derive(Subcommand)]
enum Command {
Devices(devices::DeviceArgs),
SendTab(send_tab::SendTabArgs),
Disconnect,
}

fn main() -> Result<()> {
let cli = Cli::parse();
viaduct_reqwest::use_reqwest_backend();

println!();
let account = load_account(&cli)?;
match cli.command {
Command::Devices(args) => devices::run(&account, args),
Command::SendTab(args) => send_tab::run(&account, args),
Command::Disconnect => {
account.disconnect();
Ok(())
}
}?;

Ok(())
}

fn load_account(cli: &Cli) -> Result<FirefoxAccount> {
let config = FxaConfig {
server: match cli.server {
Server::Release => FxaServer::Release,
Server::Stable => FxaServer::Stable,
Server::Stage => FxaServer::Stage,
Server::China => FxaServer::China,
Server::LocalDev => FxaServer::LocalDev,
},
redirect_uri: REDIRECT_URI.into(),
client_id: CLIENT_ID.into(),
token_server_url_override: None,
};
get_cli_fxa(config, CREDENTIALS_PATH).map(|cli| cli.account)
}

pub fn persist_fxa_state(acct: &FirefoxAccount) -> Result<()> {
let json = acct.to_json().unwrap();
Ok(fs::write(CREDENTIALS_PATH, json)?)
}

0 comments on commit 6f74754

Please sign in to comment.