github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/apiserver/client_auth_root.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package apiserver
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  
     9  	"github.com/juju/juju/apiserver/common"
    10  	"github.com/juju/juju/rpc"
    11  	"github.com/juju/juju/rpc/rpcreflect"
    12  	"github.com/juju/juju/state"
    13  )
    14  
    15  // clientAuthRoot restricts API calls for users of a model. Initially the
    16  // authorisation checks are only for read only access to the model, but in the
    17  // near future, full ACL support is desirable.
    18  type clientAuthRoot struct {
    19  	finder rpc.MethodFinder
    20  	user   *state.ModelUser
    21  }
    22  
    23  // newClientAuthRoot returns a new restrictedRoot.
    24  func newClientAuthRoot(finder rpc.MethodFinder, user *state.ModelUser) *clientAuthRoot {
    25  	return &clientAuthRoot{finder, user}
    26  }
    27  
    28  // FindMethod returns a not supported error if the rootName is not one of the
    29  // facades available at the server root when there is no active model.
    30  func (r *clientAuthRoot) FindMethod(rootName string, version int, methodName string) (rpcreflect.MethodCaller, error) {
    31  	// The lookup of the name is done first to return a not found error if the
    32  	// user is looking for a method that we just don't have.
    33  	caller, err := r.finder.FindMethod(rootName, version, methodName)
    34  	if err != nil {
    35  		return nil, err
    36  	}
    37  	if r.user.ReadOnly() {
    38  		canCall := isCallAllowableByReadOnlyUser(rootName, methodName) ||
    39  			isCallReadOnly(rootName, methodName)
    40  		if !canCall {
    41  			return nil, errors.Trace(common.ErrPerm)
    42  		}
    43  	}
    44  
    45  	return caller, nil
    46  }
    47  
    48  // isCallAllowableByReadOnlyUser returns whether or not the method on the facade
    49  // can be called by a read only user.
    50  func isCallAllowableByReadOnlyUser(facade, _ /*method*/ string) bool {
    51  	// At this stage, any facade that is part of the restricted root (those
    52  	// that are accessable outside of models) are OK because the user would
    53  	// have access to those facades if they went through the controller API
    54  	// endpoint rather than a model oriented one.
    55  	return restrictedRootNames.Contains(facade)
    56  }