github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/apiserver/usermanager/usermanager.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package usermanager
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/names"
    12  
    13  	"github.com/juju/juju/state"
    14  	"github.com/juju/juju/state/api/params"
    15  	"github.com/juju/juju/state/apiserver/common"
    16  )
    17  
    18  var logger = loggo.GetLogger("juju.state.apiserver.usermanager")
    19  
    20  // UserManager defines the methods on the usermanager API end point.
    21  type UserManager interface {
    22  	AddUser(arg params.ModifyUsers) (params.ErrorResults, error)
    23  	RemoveUser(arg params.Entities) (params.ErrorResults, error)
    24  }
    25  
    26  // UserManagerAPI implements the user manager interface and is the concrete
    27  // implementation of the api end point.
    28  type UserManagerAPI struct {
    29  	state       *state.State
    30  	authorizer  common.Authorizer
    31  	getCanWrite common.GetAuthFunc
    32  	getCanRead  common.GetAuthFunc
    33  }
    34  
    35  var _ UserManager = (*UserManagerAPI)(nil)
    36  
    37  func NewUserManagerAPI(
    38  	st *state.State,
    39  	authorizer common.Authorizer,
    40  ) (*UserManagerAPI, error) {
    41  	if !authorizer.AuthClient() {
    42  		return nil, common.ErrPerm
    43  	}
    44  
    45  	// TODO(mattyw) - replace stub with real canWrite function
    46  	getCanWrite := common.AuthAlways(true)
    47  
    48  	// TODO(waigani) - replace stub with real canRead function
    49  	getCanRead := common.AuthAlways(true)
    50  	return &UserManagerAPI{
    51  			state:       st,
    52  			authorizer:  authorizer,
    53  			getCanWrite: getCanWrite,
    54  			getCanRead:  getCanRead},
    55  		nil
    56  }
    57  
    58  func (api *UserManagerAPI) AddUser(args params.ModifyUsers) (params.ErrorResults, error) {
    59  	result := params.ErrorResults{
    60  		Results: make([]params.ErrorResult, len(args.Changes)),
    61  	}
    62  	if len(args.Changes) == 0 {
    63  		return result, nil
    64  	}
    65  	canWrite, err := api.getCanWrite()
    66  	if err != nil {
    67  		result.Results[0].Error = common.ServerError(err)
    68  		return result, err
    69  	}
    70  	user := api.getLoggedInUser()
    71  	if user == nil {
    72  		return result, fmt.Errorf("api connection is not through a user")
    73  	}
    74  	for i, arg := range args.Changes {
    75  		if !canWrite(arg.Tag) {
    76  			result.Results[0].Error = common.ServerError(common.ErrPerm)
    77  			continue
    78  		}
    79  		username := arg.Username
    80  		if username == "" {
    81  			username = arg.Tag
    82  		}
    83  		_, err := api.state.AddUser(username, arg.DisplayName, arg.Password, user.Name())
    84  		if err != nil {
    85  			err = errors.Annotate(err, "failed to create user")
    86  			result.Results[i].Error = common.ServerError(err)
    87  			continue
    88  		}
    89  	}
    90  	return result, nil
    91  }
    92  
    93  func (api *UserManagerAPI) RemoveUser(args params.Entities) (params.ErrorResults, error) {
    94  	result := params.ErrorResults{
    95  		Results: make([]params.ErrorResult, len(args.Entities)),
    96  	}
    97  	if len(args.Entities) == 0 {
    98  		return result, nil
    99  	}
   100  	canWrite, err := api.getCanWrite()
   101  	if err != nil {
   102  		return result, err
   103  	}
   104  	for i, arg := range args.Entities {
   105  		if !canWrite(arg.Tag) {
   106  			result.Results[i].Error = common.ServerError(common.ErrPerm)
   107  			continue
   108  		}
   109  		user, err := api.state.User(arg.Tag)
   110  		if err != nil {
   111  			result.Results[i].Error = common.ServerError(common.ErrPerm)
   112  			continue
   113  		}
   114  		err = user.Deactivate()
   115  		if err != nil {
   116  			result.Results[i].Error = common.ServerError(fmt.Errorf("Failed to remove user: %s", err))
   117  			continue
   118  		}
   119  	}
   120  	return result, nil
   121  }
   122  
   123  // UserInfo returns information on a user.
   124  func (api *UserManagerAPI) UserInfo(args params.Entities) (params.UserInfoResults, error) {
   125  	results := params.UserInfoResults{
   126  		Results: make([]params.UserInfoResult, len(args.Entities)),
   127  	}
   128  
   129  	canRead, err := api.getCanRead()
   130  	if err != nil {
   131  		return results, err
   132  	}
   133  	for i, userArg := range args.Entities {
   134  		if !canRead(userArg.Tag) {
   135  			results.Results[i].Error = common.ServerError(common.ErrPerm)
   136  			continue
   137  		}
   138  		tag, err := names.ParseTag(userArg.Tag, names.UserTagKind)
   139  		if err != nil {
   140  			results.Results[0].Error = common.ServerError(err)
   141  			continue
   142  		}
   143  		username := tag.Id()
   144  
   145  		user, err := api.state.User(username)
   146  		var result params.UserInfoResult
   147  		if err != nil {
   148  			if errors.IsNotFound(err) {
   149  				result.Error = common.ServerError(common.ErrPerm)
   150  			} else {
   151  				result.Error = common.ServerError(err)
   152  			}
   153  		} else {
   154  			info := params.UserInfo{
   155  				Username:       username,
   156  				DisplayName:    user.DisplayName(),
   157  				CreatedBy:      user.CreatedBy(),
   158  				DateCreated:    user.DateCreated(),
   159  				LastConnection: user.LastConnection(),
   160  			}
   161  			result.Result = &info
   162  		}
   163  		results.Results[i] = result
   164  	}
   165  
   166  	return results, nil
   167  }
   168  
   169  func (api *UserManagerAPI) getLoggedInUser() *state.User {
   170  	entity := api.authorizer.GetAuthEntity()
   171  	if user, ok := entity.(*state.User); ok {
   172  		return user
   173  	}
   174  	return nil
   175  }