github.com/safing/portbase@v0.19.5/api/endpoints_meta.go (about)

     1  package api
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"net/http"
     7  )
     8  
     9  func registerMetaEndpoints() error {
    10  	if err := RegisterEndpoint(Endpoint{
    11  		Path:        "endpoints",
    12  		Read:        PermitAnyone,
    13  		MimeType:    MimeTypeJSON,
    14  		DataFunc:    listEndpoints,
    15  		Name:        "Export API Endpoints",
    16  		Description: "Returns a list of all registered endpoints and their metadata.",
    17  	}); err != nil {
    18  		return err
    19  	}
    20  
    21  	if err := RegisterEndpoint(Endpoint{
    22  		Path:        "auth/permissions",
    23  		Read:        Dynamic,
    24  		StructFunc:  permissions,
    25  		Name:        "View Current Permissions",
    26  		Description: "Returns the current permissions assigned to the request.",
    27  	}); err != nil {
    28  		return err
    29  	}
    30  
    31  	if err := RegisterEndpoint(Endpoint{
    32  		Path:        "auth/bearer",
    33  		Read:        Dynamic,
    34  		HandlerFunc: authBearer,
    35  		Name:        "Request HTTP Bearer Auth",
    36  		Description: "Returns an HTTP Bearer Auth request, if not authenticated.",
    37  	}); err != nil {
    38  		return err
    39  	}
    40  
    41  	if err := RegisterEndpoint(Endpoint{
    42  		Path:        "auth/basic",
    43  		Read:        Dynamic,
    44  		HandlerFunc: authBasic,
    45  		Name:        "Request HTTP Basic Auth",
    46  		Description: "Returns an HTTP Basic Auth request, if not authenticated.",
    47  	}); err != nil {
    48  		return err
    49  	}
    50  
    51  	if err := RegisterEndpoint(Endpoint{
    52  		Path:        "auth/reset",
    53  		Read:        PermitAnyone,
    54  		HandlerFunc: authReset,
    55  		Name:        "Reset Authenticated Session",
    56  		Description: "Resets authentication status internally and in the browser.",
    57  	}); err != nil {
    58  		return err
    59  	}
    60  
    61  	return nil
    62  }
    63  
    64  func listEndpoints(ar *Request) (data []byte, err error) {
    65  	data, err = json.Marshal(ExportEndpoints())
    66  	return
    67  }
    68  
    69  func permissions(ar *Request) (i interface{}, err error) {
    70  	if ar.AuthToken == nil {
    71  		return nil, errors.New("authentication token missing")
    72  	}
    73  
    74  	return struct {
    75  		Read      Permission
    76  		Write     Permission
    77  		ReadRole  string
    78  		WriteRole string
    79  	}{
    80  		Read:      ar.AuthToken.Read,
    81  		Write:     ar.AuthToken.Write,
    82  		ReadRole:  ar.AuthToken.Read.Role(),
    83  		WriteRole: ar.AuthToken.Write.Role(),
    84  	}, nil
    85  }
    86  
    87  func authBearer(w http.ResponseWriter, r *http.Request) {
    88  	// Check if authenticated by checking read permission.
    89  	ar := GetAPIRequest(r)
    90  	if ar.AuthToken.Read != PermitAnyone {
    91  		TextResponse(w, r, "Authenticated.")
    92  		return
    93  	}
    94  
    95  	// Respond with desired authentication header.
    96  	w.Header().Set(
    97  		"WWW-Authenticate",
    98  		`Bearer realm="Portmaster API" domain="/"`,
    99  	)
   100  	http.Error(w, "Authorization required.", http.StatusUnauthorized)
   101  }
   102  
   103  func authBasic(w http.ResponseWriter, r *http.Request) {
   104  	// Check if authenticated by checking read permission.
   105  	ar := GetAPIRequest(r)
   106  	if ar.AuthToken.Read != PermitAnyone {
   107  		TextResponse(w, r, "Authenticated.")
   108  		return
   109  	}
   110  
   111  	// Respond with desired authentication header.
   112  	w.Header().Set(
   113  		"WWW-Authenticate",
   114  		`Basic realm="Portmaster API" domain="/"`,
   115  	)
   116  	http.Error(w, "Authorization required.", http.StatusUnauthorized)
   117  }
   118  
   119  func authReset(w http.ResponseWriter, r *http.Request) {
   120  	// Get session cookie from request and delete session if exists.
   121  	c, err := r.Cookie(sessionCookieName)
   122  	if err == nil {
   123  		deleteSession(c.Value)
   124  	}
   125  
   126  	// Delete session and cookie.
   127  	http.SetCookie(w, &http.Cookie{
   128  		Name:   sessionCookieName,
   129  		MaxAge: -1, // MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
   130  	})
   131  
   132  	// Request client to also reset all data.
   133  	w.Header().Set("Clear-Site-Data", "*")
   134  
   135  	// Set HTTP Auth Realm without requesting authorization.
   136  	w.Header().Set("WWW-Authenticate", `None realm="Portmaster API"`)
   137  
   138  	// Reply with 401 Unauthorized in order to clear HTTP Basic Auth data.
   139  	http.Error(w, "Session deleted.", http.StatusUnauthorized)
   140  }