Skip to main content

Campus network control (cnc)

Project description

cuit-campus-network

Github Social Preview

Python Version License Last Commit GitHub stars GitHub forks

English | 简体中文

Introduction

cnc is a third-party campus network client for schools using Ruijie as the campus network provider. As a Python CLI tool, cnc is easy to install and lets you perform operations such as login, logout, status check, and keep-alive.

Plan

  • :chart_with_upwards_trend: Add images
  • :pencil2: Add flowchart(Using Mermaid
  • :iphone: Support iOS Shortcut
  • :rocket: Support multiple ISP
  • :school: Support multiple places(dormitory, classroom, etc.)
  • :eyes: Add graphical user interface(maybe Next.js or Gradio
  • :hammer: Upload to PyPI
  • :beer: Upload to Homebrew
  • :file_folder: Package into a container

Install

  • Pip
pip install cnc
  • Source Code

    1. Clone this repository
    git clone https://github.com/ermengchao/cnc . && cd cnc
    
    1. Install the cnc package
    pip install -e .
    

Usage

:exclamation::exclamation: Before first usage, please run

cnc login

to create the cache. Cache example:

portal_url: http://10.254.241.19
updated_at: 1766905991
  • portal_url: Portal URL for authentication (varies by school)
  • updated_at: Cache creation time

If the cache is not created properly, all commands except login may be limited.

After the cache is created, you can use cnc normally. Supported operations:

  • login: Log in to campus network
  • logout: Log out of campus network
  • status: Check campus network status
  • keep-alive: Keep login alive via a persistent script (recommended with systemd)
  • help: Show usage help

login

Use:

cnc login --user-id 2023083061 --password ****** --service 电信

Input:

  • user-id: Campus network account. You can also set CNC_USER_ID
  • password: Campus network password. You can also set CNC_PASSWORD
  • service: ISP. You can also set CNC_SERVICE

Output:

  • Login successful: Login succeeded
  • Already online. Login skipped.: Already online, login skipped
  • You appear to be offline. Login skipped.: Not connected to campus network
  • Login failed: <error>: Login failed with server error
  • State is missing/expired but you appear to be already authenticated...: Cache missing

logout

Use:

cnc logout

Input:

  • None (uses cached portal_url)

Output:

  • Logged out successfully: Logout succeeded
  • Already offline. Logout skipped.: Already offline, logout skipped
  • Logout failed: <error>: Logout failed with server error
  • No cached portal_url found. Please run cnc login once to initialize the cache before using other commands.: Cache missing

status

Use:

cnc status

Input:

  • None (uses cached portal_url)

Output:

  • Status: on_campus_unauth: On campus but unauthenticated
  • Status: on_campus_auth: On campus and authenticated
  • Status: off_campus: Off campus
  • Status: unknown: Status unknown
  • No cached portal_url found. Please run cnc login once to initialize the cache before using other commands.: Cache missing

keep-alive

Use (polling mode, default):

cnc keep-alive --polling --interval-seconds 300

Use (daily relogin mode):

cnc keep-alive --relogin --user-id 2023083061 --password ****** --service 电信 --run-at 05:00

Input:

  • --polling or --relogin (choose one)
  • --interval-seconds: Polling interval in seconds (polling mode only, default 300)
  • --user-id, --password, --service: Relogin mode only (can also use CNC_USER_ID, CNC_PASSWORD, CNC_SERVICE)
  • --run-at: Daily relogin time (relogin mode only, HH:MM, default 05:00)

Output:

  • Choose only one mode: --polling or --relogin: Mode conflict
  • relogin mode requires --user-id, --password, and --service: Missing relogin args
  • Keep-alive failed: <error>: Keep-alive failed
  • No cached portal_url found. Please run cnc login once to initialize the cache before using other commands.: Cache missing

help

Use:

cnc help
cnc help login

Input:

  • Optional subcommand name

Output:

  • Prints CLI help text

Process

flowchart TD
    A["CampusNetClient 初始化"] --> B["StateStore 读写 state.yaml"]

    A --> S["status()"]
    S --> S1{"有 cached portal_url?"}
    S1 -- "否" --> S2["StateError: 先登录缓存"]
    S1 -- "是" --> S3["detect_network_status(redirect_url)"]
    S3 --> S4{"结果 UNKNOWN?"}
    S4 -- "否" --> S5["返回 NetworkState"]
    S4 -- "是" --> S6["_status_from_portal_url(cached portal_url)"]

    A --> E["ensure_state()"]
    E --> E1{"_state_has_fresh_portal_url?"}
    E1 -- "是" --> E2["返回 cached"]
    E1 -- "否" --> E3["status()"]
    E3 --> E4{"ON_CAMPUS_AUTH?"}
    E4 -- "是" --> E5["NeedUnauthed"]
    E4 -- "否" --> E6["get_portal_info → 保存 state"]

    A --> L["login(user_id, password, service)"]
    L --> L1{"cached portal_url?"}
    L1 -- "是" --> L2["_status_from_portal_url"]
    L1 -- "否" --> L3["detect_network_status"]
    L2 --> L4{"ON_CAMPUS_AUTH?"}
    L3 --> L4
    L4 -- "是" --> L5["AlreadyOnline: Login skipped"]
    L4 -- "否" --> L6{"OFF_CAMPUS?"}
    L6 -- "是" --> L7["AlreadyOffline: Login skipped"]
    L6 -- "否" --> L8["get_portal_info → portal_url/query → save"]
    L8 --> L9["do_login(...)"]

    A --> O["logout()"]
    O --> O1{"cached portal_url?"}
    O1 -- "否" --> O2["StateError: no cache"]
    O1 -- "是" --> O3["_status_from_portal_url"]
    O3 --> O4{"ON_CAMPUS_UNAUTH 或 OFF_CAMPUS?"}
    O4 -- "是" --> O5["AlreadyOffline: Logout skipped"]
    O4 -- "否" --> O6{"UNKNOWN?"}
    O6 -- "是" --> O7["StateError: unknown"]
    O6 -- "否" --> O8["get_portal_info → save"]
    O8 --> O9{"portal_url 存在?"}
    O9 -- "否" --> O10["StateError: no portal_url"]
    O9 -- "是" --> O11["do_logout(...)"]

    subgraph Helper["Helper"]
        H1["_state_has_fresh_portal_url"]
        H2["_status_from_portal_url"]
    end

Principles

Optional. If you are interested, you can refer to the steps below. If you run into any issues, feel free to open an issue!

Login principle

Login is essentially a POST request to http://{portal_url}/eportal/Interface.do?method=login, with the following fields:

# Header
-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \

# Body
# User info
--data-urlencode "userId=$userId" \
--data-urlencode "password=$password" \
--data-urlencode "service=$service" \
--data-urlencode "queryString=$queryString" \
# Placeholder fields
--data-urlencode 'operatorPwd=' \
--data-urlencode 'operatorUserId=' \
--data-urlencode 'validcode=' \
--data-urlencode 'passwordEncrypt=false'

Logout principle

Logout is essentially a POST request to http://{portal_url}/eportal/Interface.do?method=logout. Unlike login, logout does not require a request body.

Status principle

Status is essentially a GET request to http://{portal_url}/eportal/redirectortosuccess.jsp, and you can determine the state by checking the Location header:

  • Authenticated: Location=http://{portal_url}/eportal/./success.jsp
  • Unauthenticated: Location=http://123.123.123.123/
  • Off campus: request timeout

LICENSE

MIT LICENSE

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cnc_cli-0.1.0.tar.gz (16.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cnc_cli-0.1.0-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

Details for the file cnc_cli-0.1.0.tar.gz.

File metadata

  • Download URL: cnc_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for cnc_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 af0ec901a0960d367c98b596cfa3a5e97f53c1f72283f033a35458955165d33f
MD5 7f736d9414facaac3957efcb804b7035
BLAKE2b-256 461807511ee106a15aa85a2373796199c4f957e29d2916640da85907de5d29b9

See more details on using hashes here.

File details

Details for the file cnc_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cnc_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for cnc_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 80dd050dba0329badac3981e9f1add176eaea6dfa0de9d288b8ad4b31cd774e9
MD5 8a668052f9b6628e0399c9fcd85a429f
BLAKE2b-256 ef4e1d9bf10a6c8030c4199ab6131c9d8f1c15f3fedc6edb12efebea68daa50a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page