mirror of
https://github.com/0x1d/rcond.git
synced 2025-12-14 18:25:21 +01:00
feat: return json responses
This commit is contained in:
169
api/rcond.yaml
169
api/rcond.yaml
@@ -15,6 +15,14 @@ components:
|
|||||||
in: header
|
in: header
|
||||||
name: X-API-Token
|
name: X-API-Token
|
||||||
description: API token for authentication
|
description: API token for authentication
|
||||||
|
schemas:
|
||||||
|
Error:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
description: Error message
|
||||||
|
example: "some error message"
|
||||||
|
|
||||||
security:
|
security:
|
||||||
- ApiKeyAuth: []
|
- ApiKeyAuth: []
|
||||||
@@ -36,6 +44,12 @@ paths:
|
|||||||
status:
|
status:
|
||||||
type: string
|
type: string
|
||||||
example: "healthy"
|
example: "healthy"
|
||||||
|
'500':
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/network/ap:
|
/network/ap:
|
||||||
post:
|
post:
|
||||||
@@ -78,10 +92,22 @@ paths:
|
|||||||
example: "7d706027-727c-4d4c-a816-f0e1b99db8ab"
|
example: "7d706027-727c-4d4c-a816-f0e1b99db8ab"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload
|
description: Invalid request payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/network/interface/{interface}:
|
/network/interface/{interface}:
|
||||||
put:
|
put:
|
||||||
@@ -111,12 +137,32 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Network interface brought up successfully
|
description: Network interface brought up successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "success"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload
|
description: Invalid request payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
delete:
|
delete:
|
||||||
summary: Deactivate network connection
|
summary: Deactivate network connection
|
||||||
description: Deactivates the specified network connection
|
description: Deactivates the specified network connection
|
||||||
@@ -131,12 +177,32 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Network interface brought down successfully
|
description: Network interface brought down successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "success"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload
|
description: Invalid request payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/network/connection/{uuid}:
|
/network/connection/{uuid}:
|
||||||
delete:
|
delete:
|
||||||
@@ -153,12 +219,32 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Connection profile removed successfully
|
description: Connection profile removed successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "success"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload
|
description: Invalid request payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/hostname:
|
/hostname:
|
||||||
get:
|
get:
|
||||||
@@ -168,15 +254,26 @@ paths:
|
|||||||
'200':
|
'200':
|
||||||
description: Hostname retrieved successfully
|
description: Hostname retrieved successfully
|
||||||
content:
|
content:
|
||||||
text/plain:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: object
|
||||||
description: Current hostname
|
properties:
|
||||||
example: "MyHostname"
|
hostname:
|
||||||
|
type: string
|
||||||
|
description: Current hostname
|
||||||
|
example: "MyHostname"
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
post:
|
post:
|
||||||
summary: Set system hostname
|
summary: Set system hostname
|
||||||
description: Sets a new system hostname
|
description: Sets a new system hostname
|
||||||
@@ -196,12 +293,32 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Hostname set successfully
|
description: Hostname set successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "success"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload
|
description: Invalid request payload
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/users/{user}/keys:
|
/users/{user}/keys:
|
||||||
post:
|
post:
|
||||||
@@ -232,17 +349,32 @@ paths:
|
|||||||
'200':
|
'200':
|
||||||
description: Key added successfully
|
description: Key added successfully
|
||||||
content:
|
content:
|
||||||
text/plain:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: object
|
||||||
description: Fingerprint of the added key
|
properties:
|
||||||
example: "SHA256:abcdef1234567890..."
|
fingerprint:
|
||||||
|
type: string
|
||||||
|
description: Fingerprint of the added key
|
||||||
|
example: "SHA256:abcdef1234567890..."
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload or SSH key format
|
description: Invalid request payload or SSH key format
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|
||||||
/users/{user}/keys/{fingerprint}:
|
/users/{user}/keys/{fingerprint}:
|
||||||
delete:
|
delete:
|
||||||
@@ -261,15 +393,34 @@ paths:
|
|||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
format: string
|
|
||||||
description: URL-safe Base64 encoded fingerprint of the key to remove
|
description: URL-safe Base64 encoded fingerprint of the key to remove
|
||||||
example: "U0hBMjU2OmFiY2RlZjEyMzQ1Njc4OTAuLi4="
|
example: "U0hBMjU2OmFiY2RlZjEyMzQ1Njc4OTAuLi4="
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: Key removed successfully
|
description: Key removed successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "success"
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request payload or fingerprint
|
description: Invalid request payload or fingerprint
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'401':
|
'401':
|
||||||
description: Unauthorized - invalid or missing API token
|
description: Unauthorized - invalid or missing API token
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
'500':
|
'500':
|
||||||
description: Internal server error
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
|||||||
@@ -11,10 +11,6 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
NETWORK_CONNECTION_UUID = "7d706027-727c-4d4c-a816-f0e1b99db8ab"
|
|
||||||
)
|
|
||||||
|
|
||||||
type configureAPRequest struct {
|
type configureAPRequest struct {
|
||||||
Interface string `json:"interface"`
|
Interface string `json:"interface"`
|
||||||
SSID string `json:"ssid"`
|
SSID string `json:"ssid"`
|
||||||
@@ -34,15 +30,25 @@ type authorizedKeyRequest struct {
|
|||||||
PubKey string `json:"pubkey"`
|
PubKey string `json:"pubkey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errorResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeError(w http.ResponseWriter, message string, code int) {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(code)
|
||||||
|
json.NewEncoder(w).Encode(errorResponse{Error: message})
|
||||||
|
}
|
||||||
|
|
||||||
func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req configureAPRequest
|
var req configureAPRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
writeError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +56,7 @@ func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
|||||||
uuid, err := network.ConfigureAP(req.Interface, req.SSID, req.Password)
|
uuid, err := network.ConfigureAP(req.Interface, req.SSID, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to configure access point on interface %s: %v", req.Interface, err)
|
log.Printf("Failed to configure access point on interface %s: %v", req.Interface, err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("Successfully configured access point on interface %s with UUID %s", req.Interface, uuid)
|
log.Printf("Successfully configured access point on interface %s with UUID %s", req.Interface, uuid)
|
||||||
@@ -64,19 +70,20 @@ func HandleConfigureAP(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||||
log.Printf("Failed to encode response: %v", err)
|
log.Printf("Failed to encode response: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleNetworkUp(w http.ResponseWriter, r *http.Request) {
|
func HandleNetworkUp(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPut {
|
if r.Method != http.MethodPut {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req networkUpRequest
|
var req networkUpRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
writeError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@@ -85,84 +92,90 @@ func HandleNetworkUp(w http.ResponseWriter, r *http.Request) {
|
|||||||
log.Printf("Bringing up network interface %s with UUID %s", iface, req.UUID)
|
log.Printf("Bringing up network interface %s with UUID %s", iface, req.UUID)
|
||||||
if err := network.Up(iface, req.UUID); err != nil {
|
if err := network.Up(iface, req.UUID); err != nil {
|
||||||
log.Printf("Failed to bring up network interface %s: %v", iface, err)
|
log.Printf("Failed to bring up network interface %s: %v", iface, err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Printf("Successfully brought up network interface %s", iface)
|
log.Printf("Successfully brought up network interface %s", iface)
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleNetworkDown(w http.ResponseWriter, r *http.Request) {
|
func HandleNetworkDown(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodDelete {
|
if r.Method != http.MethodDelete {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
iface := vars["interface"]
|
iface := vars["interface"]
|
||||||
if err := network.Down(iface); err != nil {
|
if err := network.Down(iface); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleNetworkRemove(w http.ResponseWriter, r *http.Request) {
|
func HandleNetworkRemove(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodDelete {
|
if r.Method != http.MethodDelete {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
uuid := vars["uuid"]
|
uuid := vars["uuid"]
|
||||||
if err := network.Remove(uuid); err != nil {
|
if err := network.Remove(uuid); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleGetHostname(w http.ResponseWriter, r *http.Request) {
|
func HandleGetHostname(w http.ResponseWriter, r *http.Request) {
|
||||||
hostname, err := network.GetHostname()
|
hostname, err := network.GetHostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Write([]byte(hostname))
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"hostname": hostname})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleSetHostname(w http.ResponseWriter, r *http.Request) {
|
func HandleSetHostname(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req setHostnameRequest
|
var req setHostnameRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
writeError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := network.SetHostname(req.Hostname); err != nil {
|
if err := network.SetHostname(req.Hostname); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleAddAuthorizedKey(w http.ResponseWriter, r *http.Request) {
|
func HandleAddAuthorizedKey(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var req authorizedKeyRequest
|
var req authorizedKeyRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
writeError(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
@@ -170,42 +183,44 @@ func HandleAddAuthorizedKey(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
fingerprint, err := user.AddAuthorizedKey(username, req.PubKey)
|
fingerprint, err := user.AddAuthorizedKey(username, req.PubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Write([]byte(fingerprint))
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"fingerprint": fingerprint})
|
||||||
}
|
}
|
||||||
|
|
||||||
func HandleRemoveAuthorizedKey(w http.ResponseWriter, r *http.Request) {
|
func HandleRemoveAuthorizedKey(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodDelete {
|
if r.Method != http.MethodDelete {
|
||||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
writeError(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
fingerprint := vars["fingerprint"]
|
fingerprint := vars["fingerprint"]
|
||||||
if fingerprint == "" {
|
if fingerprint == "" {
|
||||||
http.Error(w, "fingerprint parameter is required", http.StatusBadRequest)
|
writeError(w, "fingerprint parameter is required", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
username := vars["user"]
|
username := vars["user"]
|
||||||
if username == "" {
|
if username == "" {
|
||||||
http.Error(w, "user parameter is required", http.StatusBadRequest)
|
writeError(w, "user parameter is required", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fingerprintBytes, err := base64.RawURLEncoding.DecodeString(fingerprint)
|
fingerprintBytes, err := base64.RawURLEncoding.DecodeString(fingerprint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "invalid fingerprint base64", http.StatusBadRequest)
|
writeError(w, "invalid fingerprint base64", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := user.RemoveAuthorizedKey(username, string(fingerprintBytes)); err != nil {
|
if err := user.RemoveAuthorizedKey(username, string(fingerprintBytes)); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
writeError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
json.NewEncoder(w).Encode(map[string]string{"status": "success"})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user