diff options
Diffstat (limited to 'docs/archive/2025-11-04-evening/2025-11-04-git-http-backend-validation.md')
| -rw-r--r-- | docs/archive/2025-11-04-evening/2025-11-04-git-http-backend-validation.md | 247 |
1 files changed, 0 insertions, 247 deletions
diff --git a/docs/archive/2025-11-04-evening/2025-11-04-git-http-backend-validation.md b/docs/archive/2025-11-04-evening/2025-11-04-git-http-backend-validation.md deleted file mode 100644 index d383b9f..0000000 --- a/docs/archive/2025-11-04-evening/2025-11-04-git-http-backend-validation.md +++ /dev/null | |||
| @@ -1,247 +0,0 @@ | |||
| 1 | **ARCHIVED: 2025-11-04** | ||
| 2 | **Reason:** Analysis complete, validated hybrid approach | ||
| 3 | **Outcome:** Will use git-http-backend (forked) + git2 + system git | ||
| 4 | |||
| 5 | --- | ||
| 6 | |||
| 7 | # Analysis Summary: git-http-backend Validation | ||
| 8 | |||
| 9 | **Date:** 2025-11-04 | ||
| 10 | **Status:** ✅ ARCHIVED - Analysis Complete | ||
| 11 | |||
| 12 | --- | ||
| 13 | |||
| 14 | ## TL;DR | ||
| 15 | |||
| 16 | ✅ **VALIDATED:** The hybrid approach in `current_status.md` is sound | ||
| 17 | ⚠️ **CAVEAT:** Must fork/vendor `git-http-backend` crate for inline authorization | ||
| 18 | ✅ **READY:** Can proceed with implementation | ||
| 19 | |||
| 20 | --- | ||
| 21 | |||
| 22 | ## Key Findings | ||
| 23 | |||
| 24 | ### 1. git-http-backend Crate (v0.1.3) | ||
| 25 | |||
| 26 | **What it provides:** | ||
| 27 | - ✅ Actix-web based Git Smart HTTP handlers | ||
| 28 | - ✅ Upload-pack (clone/fetch) - works as-is | ||
| 29 | - ✅ Receive-pack (push) - **needs modification** | ||
| 30 | - ✅ Info/refs advertisement | ||
| 31 | - ✅ Gzip compression support | ||
| 32 | - ✅ Streaming responses | ||
| 33 | |||
| 34 | **What it lacks:** | ||
| 35 | - ❌ Authorization hooks (spawns git immediately) | ||
| 36 | - ❌ CORS headers (needed for web clients) | ||
| 37 | - ❌ Protocol parsing (can't inspect push data) | ||
| 38 | - ❌ Proper error handling (uses eprintln!) | ||
| 39 | |||
| 40 | ### 2. Critical Handler: git_receive_pack | ||
| 41 | |||
| 42 | **Current flow:** | ||
| 43 | ``` | ||
| 44 | Request → Validate bare repo → Spawn git → Stream response | ||
| 45 | ``` | ||
| 46 | |||
| 47 | **What we need:** | ||
| 48 | ``` | ||
| 49 | Request → Validate bare repo → Parse ref updates → Validate against Nostr state → Spawn git (if authorized) → Stream response | ||
| 50 | ↑ | ||
| 51 | ADD THIS | ||
| 52 | ``` | ||
| 53 | |||
| 54 | **Can't achieve with unmodified crate!** | ||
| 55 | |||
| 56 | ### 3. Recommended Solution | ||
| 57 | |||
| 58 | **Fork the crate and modify `git_receive_pack.rs`:** | ||
| 59 | |||
| 60 | ```rust | ||
| 61 | pub async fn git_receive_pack( | ||
| 62 | request: HttpRequest, | ||
| 63 | mut payload: Payload, | ||
| 64 | service: web::Data<impl GitConfig>, | ||
| 65 | validator: web::Data<PushValidator>, // ← ADD | ||
| 66 | ) -> impl Responder { | ||
| 67 | // ... existing path resolution and bare check ... | ||
| 68 | |||
| 69 | // Read request body | ||
| 70 | let body_data = read_and_decode_body(&mut payload, &request).await?; | ||
| 71 | |||
| 72 | // ← ADD: Parse ref updates | ||
| 73 | let ref_updates = parse_receive_pack_request(&body_data)?; | ||
| 74 | |||
| 75 | // ← ADD: Validate authorization | ||
| 76 | let (npub, identifier) = extract_repo_info(&request.uri().path())?; | ||
| 77 | if let Err(e) = validator.validate_push(&npub, &identifier, &ref_updates).await { | ||
| 78 | return HttpResponse::Forbidden() | ||
| 79 | .json(json!({ | ||
| 80 | "error": "unauthorized", | ||
| 81 | "message": e.to_string(), | ||
| 82 | })); | ||
| 83 | } | ||
| 84 | |||
| 85 | // Only spawn git if authorized | ||
| 86 | let mut cmd = Command::new("git"); | ||
| 87 | cmd.arg("receive-pack"); | ||
| 88 | // ... rest of existing code ... | ||
| 89 | } | ||
| 90 | ``` | ||
| 91 | |||
| 92 | --- | ||
| 93 | |||
| 94 | ## Updated Implementation Plan | ||
| 95 | |||
| 96 | ### Phase 0: Setup (NEW) | ||
| 97 | 1. Fork git-http-backend repository | ||
| 98 | 2. Add as git submodule or vendor code | ||
| 99 | 3. Verify existing functionality works | ||
| 100 | 4. Add to Cargo.toml | ||
| 101 | |||
| 102 | ### Phase 1: Foundation | ||
| 103 | 1. Add git2 dependency | ||
| 104 | 2. Implement GitRepository (repo management) | ||
| 105 | 3. Add protocol parsing module | ||
| 106 | 4. Unit tests for both | ||
| 107 | |||
| 108 | ### Phase 2: Authorization | ||
| 109 | 1. Modify git_receive_pack handler | ||
| 110 | 2. Implement PushValidator | ||
| 111 | 3. Integration tests for validation | ||
| 112 | 4. Test unauthorized rejection | ||
| 113 | |||
| 114 | ### Phase 3: Polish | ||
| 115 | 1. Add CORS headers to all handlers | ||
| 116 | 2. Improve error messages | ||
| 117 | 3. Add tracing instead of eprintln! | ||
| 118 | 4. E2E tests with real git | ||
| 119 | |||
| 120 | --- | ||
| 121 | |||
| 122 | ## Dependencies | ||
| 123 | |||
| 124 | ```toml | ||
| 125 | [dependencies] | ||
| 126 | # Forked git-http-backend with authorization support | ||
| 127 | git-http-backend = { git = "https://github.com/our-org/git-http-backend", branch = "ngit-grasp" } | ||
| 128 | |||
| 129 | # Git repository management | ||
| 130 | git2 = "0.20" | ||
| 131 | |||
| 132 | # Already have: | ||
| 133 | actix-web = "4.9" | ||
| 134 | tokio = { version = "1", features = ["full"] } | ||
| 135 | nostr-sdk = "0.43" | ||
| 136 | ``` | ||
| 137 | |||
| 138 | --- | ||
| 139 | |||
| 140 | ## Validation of current_status.md | ||
| 141 | |||
| 142 | ### ✅ Hybrid Approach - CONFIRMED | ||
| 143 | - git-http-backend for HTTP layer ✅ (with fork) | ||
| 144 | - git2 for repository management ✅ | ||
| 145 | - System git for pack operations ✅ | ||
| 146 | |||
| 147 | ### ✅ Inline Authorization - ACHIEVABLE | ||
| 148 | - Can intercept before spawning git ✅ | ||
| 149 | - Can parse ref updates ✅ | ||
| 150 | - Can validate against Nostr state ✅ | ||
| 151 | - Can return 403 with error message ✅ | ||
| 152 | |||
| 153 | ### ⚠️ Additional Requirements | ||
| 154 | - Must fork/vendor git-http-backend | ||
| 155 | - Must implement protocol parsing | ||
| 156 | - Must add CORS support | ||
| 157 | - Must improve error handling | ||
| 158 | |||
| 159 | --- | ||
| 160 | |||
| 161 | ## Risks & Mitigations | ||
| 162 | |||
| 163 | | Risk | Impact | Mitigation | | ||
| 164 | |------|--------|------------| | ||
| 165 | | Fork maintenance | Medium | Keep changes minimal, document well | | ||
| 166 | | Protocol parsing complexity | Medium | Use git2 or implement minimal parser | | ||
| 167 | | Performance overhead | Low | Keep validation fast (< 100ms), cache state | | ||
| 168 | | Missing edge cases | Medium | Extensive testing with real git clients | | ||
| 169 | |||
| 170 | --- | ||
| 171 | |||
| 172 | ## Next Steps | ||
| 173 | |||
| 174 | 1. **Decision:** Fork vs. vendor git-http-backend? | ||
| 175 | - Fork: Keep upstream tracking, easier updates | ||
| 176 | - Vendor: Full control, no external dependency | ||
| 177 | - **Recommendation:** Fork (easier to contribute back) | ||
| 178 | |||
| 179 | 2. **Start Phase 0:** Set up fork | ||
| 180 | - Fork https://github.com/lazhenyi/git-http-backend | ||
| 181 | - Create branch `ngit-grasp` | ||
| 182 | - Add as git submodule | ||
| 183 | |||
| 184 | 3. **Start Phase 1:** Add git2, implement GitRepository | ||
| 185 | - Write tests first (TDD) | ||
| 186 | - Focus on bare repo creation, ref management | ||
| 187 | |||
| 188 | 4. **Add protocol parsing:** Parse ref updates from pack protocol | ||
| 189 | - Research: Can git2 help? | ||
| 190 | - Or implement minimal parser | ||
| 191 | - Unit tests for various push scenarios | ||
| 192 | |||
| 193 | 5. **Modify receive-pack:** Add authorization logic | ||
| 194 | - Integration tests for validation | ||
| 195 | - Test rejection scenarios | ||
| 196 | |||
| 197 | --- | ||
| 198 | |||
| 199 | ## Questions for Review | ||
| 200 | |||
| 201 | 1. **Fork vs. Vendor?** | ||
| 202 | - Recommendation: Fork (can contribute back, easier updates) | ||
| 203 | |||
| 204 | 2. **Protocol parsing?** | ||
| 205 | - Option A: Use git2 if it provides parsing | ||
| 206 | - Option B: Implement minimal parser (just ref updates) | ||
| 207 | - Recommendation: Research git2 first, then decide | ||
| 208 | |||
| 209 | 3. **CORS policy?** | ||
| 210 | - Allow all origins (`*`) for now? | ||
| 211 | - Or restrict to configured domains? | ||
| 212 | - Recommendation: Start with `*`, make configurable later | ||
| 213 | |||
| 214 | 4. **Error detail?** | ||
| 215 | - How much info in 403 responses? | ||
| 216 | - Show ref updates that failed? | ||
| 217 | - Show expected vs. actual commit? | ||
| 218 | - Recommendation: Detailed errors for better DX | ||
| 219 | |||
| 220 | 5. **Performance target?** | ||
| 221 | - < 100ms for auth validation? | ||
| 222 | - Cache state events? | ||
| 223 | - Recommendation: Yes to both | ||
| 224 | |||
| 225 | --- | ||
| 226 | |||
| 227 | ## Conclusion | ||
| 228 | |||
| 229 | ✅ **The hybrid approach is validated and sound** | ||
| 230 | |||
| 231 | ⚠️ **Must fork git-http-backend for inline authorization** | ||
| 232 | |||
| 233 | ✅ **Ready to proceed with implementation** | ||
| 234 | |||
| 235 | **Confidence Level:** High (95%) | ||
| 236 | |||
| 237 | The crate provides exactly what we need as a foundation. The modifications required are straightforward and well-scoped. The main work is: | ||
| 238 | 1. Fork setup | ||
| 239 | 2. Protocol parsing | ||
| 240 | 3. Authorization integration | ||
| 241 | 4. CORS and polish | ||
| 242 | |||
| 243 | All achievable within the 4-week timeline. | ||
| 244 | |||
| 245 | --- | ||
| 246 | |||
| 247 | **Next:** Review this analysis, make fork vs. vendor decision, then start Phase 0. | ||