diff --git a/README.md b/README.md index 9c35a5b..a8bcf8d 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,9 @@ Usage: bitsrun status [OPTIONS] Check current network login status. Options: - --json / --no-json Output in JSON format. - --help Show this message and exit. + --json / --no-json Output in JSON format. + -a, --auth_url TEXT Authentication portal URL. (Optional) + --help Show this message and exit. ``` > **Note**: this is the output of `bitsrun status --help`. @@ -69,6 +70,7 @@ Usage: bitsrun login/logout [OPTIONS] Options: -u, --username TEXT Your username. -p, --password TEXT Your password. + -a, --auth_url TEXT Authentication portal URL. (Optional) -v, --verbose Verbosely echo API response. --help Show this message and exit. ``` @@ -112,6 +114,19 @@ To list all possible paths for your system (including those only for backward co bitsrun config-paths ``` +### Srun at other campuses + +This script also works for other campuses using srun authentication. If your campus uses a different authentication portal, just add the `"auth_url"` field to your `bit-user.json` config file: + +```json +{ + "username": "xxxx", + "password": "xxxx", + "auth_url": "http(s)://your-portal-address" +} +``` + +Or use the `--auth_url` option in CLI commands. This makes bitsrun compatible with other schools or custom portals. ### Raycast script (macOS) ![raycast screenshot](https://user-images.githubusercontent.com/32114380/213919582-eff6d58f-1bd2-47b2-a5da-46dc6e2eaffa.png) diff --git a/src/bitsrun/cli.py b/src/bitsrun/cli.py index af498b3..e57c497 100644 --- a/src/bitsrun/cli.py +++ b/src/bitsrun/cli.py @@ -15,6 +15,7 @@ _options = [ click.option('-u', '--username', help='Your username.', required=False), click.option('-p', '--password', help='Your password.', required=False), + click.option('-a', '--auth_url', default='http://10.0.0.55', help='Authentication portal URL. (Optional)'), click.option('-v', '--verbose', is_flag=True, help='Verbosely echo API response.'), ] @@ -51,9 +52,10 @@ def config_paths(): @cli.command() @click.option('--json/--no-json', default=False, help='Output in JSON format.') -def status(json: bool): +@click.option('-a', '--auth_url', default='http://10.0.0.55', help='Authentication portal URL. (Optional)') +def status(json: bool, auth_url: str): """Check current network login status.""" - login_status = get_login_status() + login_status = get_login_status(auth_url) # Output in JSON format if `--json` is passed, then exit if json: @@ -76,19 +78,19 @@ def status(json: bool): @cli.command() @add_options(_options) -def login(username, password, verbose): +def login(username, password, auth_url, verbose): """Log into the BIT network.""" - do_action('login', username, password, verbose) + do_action('login', username, password, auth_url, verbose) @cli.command() @add_options(_options) -def logout(username, password, verbose): +def logout(username, password, auth_url, verbose): """Log out of the BIT network.""" - do_action('logout', username, password, verbose) + do_action('logout', username, password, auth_url, verbose) -def do_action(action, username, password, verbose): +def do_action(action, username, password, auth_url, verbose): # Support reading password from stdin when not passed via `--password` if username and not password: password = getpass(prompt='Please enter your password: ') @@ -97,7 +99,7 @@ def do_action(action, username, password, verbose): # Try to read username and password from args provided. If none, look for config # files in possible paths. If none, fail and prompt user to provide one. if username and password: - user = User(username, password) + user = User(username, password, auth_url) elif conf := read_config(): if verbose: click.echo( diff --git a/src/bitsrun/user.py b/src/bitsrun/user.py index cd5216b..8814831 100644 --- a/src/bitsrun/user.py +++ b/src/bitsrun/user.py @@ -9,12 +9,11 @@ from bitsrun.models import LoginStatusRespType, UserResponseType from bitsrun.utils import fkbase64, xencode -_API_BASE = 'http://10.0.0.55' _TYPE_CONST = 1 _N_CONST = 200 -def get_login_status(client: Optional[httpx.Client] = None) -> LoginStatusRespType: +def get_login_status(auth_url, client: Optional[httpx.Client] = None) -> LoginStatusRespType: """Get current login status of the device. Note: @@ -31,19 +30,20 @@ def get_login_status(client: Optional[httpx.Client] = None) -> LoginStatusRespTy """ if not client: - client = httpx.Client(base_url=_API_BASE) + client = httpx.Client(base_url=auth_url) resp = client.get('/cgi-bin/rad_user_info', params={'callback': 'jsonp'}) return json.loads(resp.text[6:-1]) class User: - def __init__(self, username: str, password: str): + def __init__(self, username: str, password: str, auth_url: str='http://10.0.0.55'): self.username = username self.password = password + self.auth_url = auth_url # Initialize reused httpx client - self.client = httpx.Client(base_url=_API_BASE) + self.client = httpx.Client(base_url=self.auth_url) # Visit another site using HTTP, and let srun redirect to 10.0.0.55 # with url params (ac_id, theme, wlanuserip, etc.) @@ -58,7 +58,7 @@ def __init__(self, username: str, password: str): self.acid = resp_valid.url.params.get('ac_id') # Check current login status and get device `online_ip` - login_status = get_login_status(client=self.client) + login_status = get_login_status(auth_url=self.auth_url, client=self.client) self.ip = login_status.get('online_ip') self.logged_in_user = login_status.get('user_name')