// ServerError returns an error suitable for returning to an API // client, with an error code suitable for various kinds of errors // generated in packages outside the API. func ServerError(err error) *params.Error { if err == nil { return nil } logger.Tracef("server RPC error %v", errors.Details(err)) msg := err.Error() // Skip past annotations when looking for the code. err = errors.Cause(err) code, ok := singletonCode(err) var info *params.ErrorInfo switch { case ok: case errors.IsUnauthorized(err): code = params.CodeUnauthorized case errors.IsNotFound(err): code = params.CodeNotFound case errors.IsUserNotFound(err): code = params.CodeUserNotFound case errors.IsAlreadyExists(err): code = params.CodeAlreadyExists case errors.IsNotAssigned(err): code = params.CodeNotAssigned case state.IsHasAssignedUnitsError(err): code = params.CodeHasAssignedUnits case state.IsHasHostedModelsError(err): code = params.CodeHasHostedModels case isNoAddressSetError(err): code = params.CodeNoAddressSet case errors.IsNotProvisioned(err): code = params.CodeNotProvisioned case IsUpgradeInProgressError(err): code = params.CodeUpgradeInProgress case state.IsHasAttachmentsError(err): code = params.CodeMachineHasAttachedStorage case isUnknownModelError(err): code = params.CodeModelNotFound case errors.IsNotSupported(err): code = params.CodeNotSupported case errors.IsBadRequest(err): code = params.CodeBadRequest case errors.IsMethodNotAllowed(err): code = params.CodeMethodNotAllowed default: if err, ok := err.(*DischargeRequiredError); ok { code = params.CodeDischargeRequired info = ¶ms.ErrorInfo{ Macaroon: err.Macaroon, // One macaroon fits all. MacaroonPath: "/", } break } code = params.ErrCode(err) } return ¶ms.Error{ Message: msg, Code: code, Info: info, } }
// RemoveUser permanently removes a user from the current controller for each // entity provided. While the user is permanently removed we keep it's // information around for auditing purposes. // TODO(redir): Add information about getting deleted user information when we // add that capability. func (api *UserManagerAPI) RemoveUser(entities params.Entities) (params.ErrorResults, error) { var deletions params.ErrorResults if err := api.check.ChangeAllowed(); err != nil { return deletions, errors.Trace(err) } // Get a handle on the controller model. controllerModel, err := api.state.ControllerModel() if err != nil { return deletions, errors.Trace(err) } // Create the results list to populate. deletions.Results = make([]params.ErrorResult, len(entities.Entities)) isSuperUser, err := api.hasControllerAdminAccess() if err != nil { return deletions, errors.Trace(err) } if !api.isAdmin && !isSuperUser { return deletions, common.ErrPerm } // Remove the entities. for i, e := range entities.Entities { user, err := names.ParseUserTag(e.Tag) if err != nil { deletions.Results[i].Error = common.ServerError(err) continue } if controllerModel.Owner().Id() == user.Id() { deletions.Results[i].Error = common.ServerError( errors.Errorf("cannot delete controller owner %q", user.Name())) continue } err = api.state.RemoveUser(user) if err != nil { if errors.IsUserNotFound(err) { deletions.Results[i].Error = common.ServerError(err) } else { deletions.Results[i].Error = common.ServerError( errors.Annotatef(err, "failed to delete user %q", user.Name())) } continue } deletions.Results[i].Error = nil } return deletions, nil }
func getAdminEmail(rl *readline.Instance, d db.DB) (string, error) { none := "" rl.SetPrompt("Enter email: ") defer rl.SetPrompt("> ") email, err := rl.Readline() if err != nil { return none, err } if err := admin.IsAdminEmail(d, email); err != nil { if errors.IsUserNotFound(err) { return email, nil } return none, err } return none, fmt.Errorf("admin %s already exists", email) }
// Users returns a slice of all users for this model. func (m *Model) Users() ([]permission.UserAccess, error) { if m.st.ModelUUID() != m.UUID() { return nil, errors.New("cannot lookup model users outside the current model") } coll, closer := m.st.getCollection(modelUsersC) defer closer() var userDocs []userAccessDoc err := coll.Find(nil).All(&userDocs) if err != nil { return nil, errors.Trace(err) } var modelUsers []permission.UserAccess for _, doc := range userDocs { // check if the User belonging to this model user has // been deleted, in this case we should not return it. userTag := names.NewUserTag(doc.UserName) if userTag.IsLocal() { _, err := m.st.User(userTag) if errors.IsUserNotFound(err) { continue } if err != nil { return nil, errors.Trace(err) } } mu, err := NewModelUserAccess(m.st, doc) if err != nil { return nil, errors.Trace(err) } modelUsers = append(modelUsers, mu) } return modelUsers, nil }