nushell-plugins/nu_plugin_auth
Jesús Pérez 2b3e574e3d # Summary
fix: help system integration, build process optimization, and plugin rebuild efficiency

## Detailed Description

This commit addresses critical issues in the help system discoverability, build process robustness, and plugin rebuild efficiency.

### 1. Help System Integration (New Feature)

**Issue**: Version-update module recipes were not discoverable
- Not shown in `just help modules`
- Not referenced in `just help`
- Not included in help navigation system
- Users had to manually run `just --list` to find update commands

**Solution**:
- Added version-update module to all help outputs
- Updated `justfiles/help.just` to document all 30+ version-update recipes
- Created new `just commands` recipe as discoverable alias for `just --list`
- Integrated version-update into help-all workflow

**Impact**:
- Version-update commands now fully discoverable via help system
- Users can find update commands with: `just help modules`, `just help`, `just commands`
- Improved overall help system navigation

**Files Modified**:
- `justfiles/help.just` (+23 lines)
  - Added version-update module to help sections
  - Added to modules list
  - Added to help-all workflow
  - New `commands` recipe showing all recipes by group

### 2. Build Process Fixes (Phase 3: Bin Archives)

#### 2a. Plugin Archive Collection Bug

**Issue**: "No plugins found to package" warning in Phase 3
- Collected 26 plugin binaries but reported 0
- Archive creation skipped because count was wrong

**Root Cause**: `each` command returns null, so `| length` returned 0
```nushell
#  OLD - each returns null
let plugin_count = (ls nu_plugin_*/target/release/nu_plugin_* | each {|p|
    cp $p.name $"($temp_dir)/"
} | length)  # Returns 0!
```

**Solution**: Separated counting from copying with proper filtering
```nushell
#  NEW - count before operations
let plugins_to_copy = (ls nu_plugin_*/target/release/nu_plugin_* | where type == "file")
let plugin_count = ($plugins_to_copy | length)
```

**Impact**:
- Now correctly collects and reports 26 plugins
- Filters out .d dependency files automatically
- Warning eliminated

#### 2b. Tar Archive Path Handling

**Issue**: Tar command failing silently with relative paths in subshell
- `cd $temp_dir` changes context unpredictably
- Relative path `../$archive_name` fails in subshell
- Archive file not created despite exit code 0

**Root Cause**: Shell context and relative path issues in Nushell `do` block

**Solution**: Used `tar -C` with absolute paths instead of `cd`
```nushell
#  OLD - unreliable context switching
do {
    cd $temp_dir
    tar -czf ../$archive_name .
}

#  NEW - absolute paths, no context switching
tar -C $temp_dir -czf $archive_path .
```

**Additional Improvements**:
- Absolute path construction using `pwd | path join`
- Better error diagnostics with exit code and stderr output
- File verification after creation

**Impact**:
- Tar archives now created successfully
- Robust path handling across platforms
- Clear error messages for debugging

#### 2c. File Size Calculation Type Error

**Issue**: Runtime error when calculating archive size
```
Error: The '/' operator does not work on values of type 'list<filesize>'
```

**Root Cause**: `ls` returns list of records, so `.size` was a list
```nushell
#  OLD - returns list<filesize>
(ls $archive_path).size / 1024 / 1024

#  NEW - returns filesize
(ls $archive_path | get 0.size) / 1024 / 1024
```

**Impact**:
- Proper file size calculation in MB
- No more type errors

**Files Modified**:
- `scripts/create_full_distribution.nu` (+58 lines, refactored plugin collection)
  - Fixed plugin counting logic
  - Improved path handling with absolute paths
  - Enhanced error diagnostics

### 3. Plugin Rebuild Optimization

**Issue**: All plugins marked for rebuild even when dependencies unchanged
- Step 4 (`update_all_plugins.nu`) touched all Cargo.toml files at 01:00:32
- Step 5 saw all files as "newer" than binaries
- Marked ALL plugins for rebuild, though cargo only rebuilt changed ones

**Root Cause**: Script always saved files, even when no changes made
```nushell
#  OLD - always saves, touching file timestamp
$updated_content | to toml | save -f $cargo_toml
```

**Solution**: Only save if content actually changed
```nushell
#  NEW - compare before writing
let original_toml = $content | to toml
let new_toml = $updated_content | to toml

if $original_toml != $new_toml {
    $updated_content | to toml | save -f $cargo_toml
}
```

**Impact**:
- Unchanged files preserve original timestamps
- Only plugins with actual dependency changes are rebuilt
- Efficient rebuild process with accurate file modification detection

**Files Modified**:
- `scripts/update_all_plugins.nu` (+12 lines, added content comparison)
  - Only touches files with real changes
  - Preserves timestamps for efficiency
  - Clearer logic and comments

### 4. Documentation

**Files Modified**:
- `CHANGELOG.md` (+56 lines)
  - Added comprehensive 2025-10-19 entry
  - Documented all fixes with root causes
  - Listed files modified and impact summary

## Technical Details

### Nushell Patterns Used

1. **Proper List Handling**:
   - `ls` returns list of records, access with `| get 0.size`
   - Filter with `where type == "file"` to exclude metadata

2. **Absolute Path Construction**:
   - `pwd | append "path" | path join` for cross-platform paths
   - Safer than string concatenation with `/`

3. **Content Comparison**:
   - Compare TOML string representation before saving
   - Preserves file timestamps for efficiency

4. **Error Diagnostics**:
   - Capture `stderr` from commands
   - Report exit codes and error messages separately

## Testing

- [x] Help system shows version-update module
- [x] `just commands` displays all recipes by group
- [x] Phase 3 bin archive creation works
- [x] Plugin collection reports correct count (26)
- [x] Tar archives created successfully
- [x] File size calculated correctly
- [x] Plugin rebuild only touches changed files
- [x] CHANGELOG updated with all changes

## Files Changed

```
38 files changed, 2721 insertions(+), 2548 deletions(-)

Core Changes:
- justfiles/help.just                  (+23)  Help system integration
- scripts/create_full_distribution.nu  (+58)  Build process fixes
- scripts/update_all_plugins.nu        (+12)  Rebuild optimization
- CHANGELOG.md                         (+56)  Documentation

Dependency Updates:
- All plugin Cargo.toml and Cargo.lock files (version consistency)
```

## Breaking Changes

None. These are bug fixes and optimizations that maintain backward compatibility.

## Migration Notes

No migration needed. Improvements are transparent to users.

## Related Issues

- Help system discoverability
- Build process Phase 3 failures
- Unnecessary plugin rebuilds
- Build process reliability

## Checklist

- [x] Changes follow Rust/Nushell idioms
- [x] Code is well-commented
- [x] Error handling is comprehensive
- [x] Documentation is updated
- [x] All changes tested
- [x] No breaking changes introduced
2025-10-19 01:17:13 +01:00
..
2025-10-19 01:17:13 +01:00

nu_plugin_auth

Nushell plugin for provisioning platform authentication.

Overview

This plugin provides native Nushell commands for authenticating with the provisioning platform's control center. It integrates with the JWT authentication system and supports MFA workflows.

Features

  • JWT Authentication - Login with username/password, receive access and refresh tokens
  • MFA Support - TOTP and WebAuthn second-factor authentication
  • Session Management - List and manage active authentication sessions
  • Secure Token Storage - Store credentials in system keyring (macOS Keychain, Windows Credential Manager, Linux Secret Service)
  • Token Verification - Verify token validity and decode claims

Commands

auth login

Login to provisioning platform with JWT authentication.

Syntax:

auth login <username> [password] [--url <control-center-url>] [--save]

Examples:

# Login with password prompt (secure)
auth login admin

# Login with password in command (less secure)
auth login admin mypassword

# Login to custom control center URL
auth login admin --url http://control.example.com:8081

# Login and save credentials to keyring
auth login admin --save

auth logout

Logout from provisioning platform (revoke tokens).

Syntax:

auth logout [--all]

Examples:

# Logout from current session
auth logout

# Logout from all active sessions
auth logout --all

auth verify

Verify current authentication token.

Syntax:

auth verify [--token <jwt-token>]

Examples:

# Verify stored authentication token
auth verify

# Verify specific token
auth verify --token eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

auth sessions

List active authentication sessions.

Syntax:

auth sessions [--active]

Examples:

# List all sessions
auth sessions

# List only active sessions
auth sessions --active

Installation

Build from source

cd provisioning/core/plugins/nushell-plugins/nu_plugin_auth
cargo build --release

Register with Nushell

plugin add target/release/nu_plugin_auth
plugin use auth
# From nushell-plugins directory
just install-plugin nu_plugin_auth

# Or using shortcut
just i nu_plugin_auth

Configuration

The plugin uses the following defaults:

  • Control Center URL: http://localhost:8081
  • Keyring Service: provisioning-platform
  • Token Storage: System keyring (platform-dependent)

Override defaults using command flags:

# Use custom control center URL
auth login admin --url https://control.production.example.com

Authentication Flow

  1. Login: User provides credentials → Plugin sends request to control center → Receives JWT tokens
  2. Token Storage: Access and refresh tokens stored in system keyring (if --save flag used)
  3. Authenticated Requests: Plugin retrieves tokens from keyring → Includes in API requests
  4. Token Refresh: Automatic refresh using refresh token when access token expires
  5. Logout: Revoke tokens at control center → Remove from keyring

Security Considerations

  • Keyring Storage: Tokens stored in OS-provided secure storage (Keychain, Credential Manager, Secret Service)
  • Password Prompts: Interactive password prompts avoid exposing passwords in shell history
  • Token Expiration: Access tokens expire after 15 minutes (configurable at control center)
  • Refresh Tokens: Valid for 7 days (configurable at control center)
  • MFA Support: Plugin supports TOTP and WebAuthn second-factor authentication

Integration with Control Center

This plugin communicates with the provisioning platform's control center REST API:

  • POST /api/auth/login - Login with credentials
  • POST /api/auth/logout - Revoke tokens
  • POST /api/auth/verify - Verify token validity
  • GET /api/auth/sessions - List active sessions

See control center API documentation for details: provisioning/platform/control-center/README.md

Development Status

Version: 0.1.0 (Initial structure)

Implementation Progress:

  • Plugin structure created (Agente 1)
  • Login command implementation (Agente 2)
  • Logout command implementation (Agente 3)
  • Verify command implementation (Agente 4)
  • Sessions command implementation (Agente 5)
  • Test suite implementation (Agente 6)

License

MIT License - See LICENSE file for details

Contributing

This plugin is part of the provisioning platform project. See main project documentation for contribution guidelines.

  • Control Center API: provisioning/platform/control-center/README.md
  • JWT Authentication: docs/architecture/JWT_AUTH_IMPLEMENTATION.md
  • MFA Implementation: docs/architecture/MFA_IMPLEMENTATION_SUMMARY.md
  • Security System: docs/architecture/ADR-009-security-system-complete.md