github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/introspection.go (about)

     1  // Copyright 2017 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiserver
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/juju/names/v5"
    10  
    11  	"github.com/juju/juju/apiserver/common"
    12  	"github.com/juju/juju/core/permission"
    13  	"github.com/juju/juju/rpc/params"
    14  )
    15  
    16  // introspectionHandler is an http.Handler that wraps an http.Handler
    17  // from the worker/introspection package, adding authentication.
    18  type introspectionHandler struct {
    19  	ctx     httpContext
    20  	handler http.Handler
    21  }
    22  
    23  // ServeHTTP is part of the http.Handler interface.
    24  func (h introspectionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    25  	if err := h.checkAuth(r); err != nil {
    26  		if err := sendError(w, err); err != nil {
    27  			logger.Debugf("%v", err)
    28  		}
    29  		return
    30  	}
    31  	h.handler.ServeHTTP(w, r)
    32  }
    33  
    34  func (h introspectionHandler) checkAuth(r *http.Request) error {
    35  	st, entity, err := h.ctx.stateAndEntityForRequestAuthenticatedUser(r)
    36  	if err != nil {
    37  		return err
    38  	}
    39  	defer st.Release()
    40  
    41  	// Users with "superuser" access on the controller,
    42  	// or "read" access on the controller model, can
    43  	// access these endpoints.
    44  
    45  	ok, err := common.HasPermission(
    46  		st.UserPermission,
    47  		entity.Tag(),
    48  		permission.SuperuserAccess,
    49  		st.ControllerTag(),
    50  	)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	if ok {
    55  		return nil
    56  	}
    57  
    58  	ok, err = common.HasPermission(
    59  		st.UserPermission,
    60  		entity.Tag(),
    61  		permission.ReadAccess,
    62  		names.NewModelTag(st.ControllerModelUUID()),
    63  	)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	if ok {
    68  		return nil
    69  	}
    70  
    71  	return &params.Error{
    72  		Code:    params.CodeForbidden,
    73  		Message: "access denied",
    74  	}
    75  }