예제 #1
0
func (wc WikisController) genWikiLinks(userRoles []string,
	wikiId string, dbName string, uri string) wikiLinks {
	//First, add links for wikiRecord in main db
	links := wikiLinks{}
	//Now check admin rights for wiki db and add links
	wikiDb := "wiki_" + wikiId
	admin := util.HasRole(userRoles, AdminRole(wikiDb)) ||
		util.HasRole(userRoles, AdminRole(MainDbName())) ||
		util.HasRole(userRoles, MasterRole())
	read := util.HasRole(userRoles, ReadRole(wikiDb))
	write := util.HasRole(userRoles, WriteRole(wikiDb))
	pageUri := uri + "/pages"
	if admin || read || write {
		links.Self = &HatLink{Href: uri, Method: "GET"}
		links.PageIndex = &HatLink{Href: pageUri, Method: "GET"}
	}
	if admin || write {
		links.Update = &HatLink{Href: uri, Method: "PUT"}
		links.CreatePage = &HatLink{Href: pageUri, Method: "POST"}
	}
	if admin {
		links.Delete = &HatLink{Href: uri, Method: "DELETE"}
	}
	return links
}
예제 #2
0
//Create a normal user
func (um *UserManager) Create(newUser *User,
	curUser *CurrentUserInfo) (string, error) {
	//Who am I?
	theUser := curUser.User

	//check for admin
	if !util.HasRole(theUser.Roles, AdminRole(MainDbName())) &&
		!util.HasRole(theUser.Roles, MasterRole()) {
		return "", NotAdminError()
	}
	//ok, now create the user
	err := um.validateUser(newUser)
	if err != nil {
		return "", err
	}
	newUser.Roles = []string{ReadRole(MainDbName()), AllUsersRole()}
	newUser.Type = "user"
	namestring := UserPrefix + newUser.UserName
	nowTime := time.Now().UTC()
	newUser.CreatedAt = nowTime
	newUser.ModifiedAt = nowTime

	userDb := Connection.SelectDB(UserDbName, AdminAuth)
	log.Printf("Creating new user account for: %v", newUser.UserName)
	return userDb.Save(newUser, namestring, "")
}
예제 #3
0
//Revoke user access
func (um *UserManager) RevokeRole(id string,
	revokeRequest *RoleRequest,
	curUser *CurrentUserInfo) (string, error) {

	theUser := curUser.User
	//Make sure user is an admin of the resource being requested
	resourceDbName := resourceDbName(revokeRequest)
	if !util.HasRole(theUser.Roles, AdminRole(MainDbName())) &&
		!util.HasRole(theUser.Roles, AdminRole(resourceDbName)) {
		//Not an admin
		return "", NotAdminError()
	}
	//Fetch the user
	userDb := Connection.SelectDB(UserDbName, AdminAuth)
	readUser := new(User)
	rev, err := userDb.Read(UserPrefix+id, readUser, nil)
	if err != nil {
		return "", err
	}
	//validate the role request
	if revokeRequest.validate() == false {
		return "", BadRequestError()
	}
	//ok, revoke the role
	revokeRole := revokeRequest.roleString()
	rev, err = Connection.RevokeRole(id, revokeRole, AdminAuth)
	if err != nil {
		return "", err
	}
	return rev, nil
}
예제 #4
0
//Get user list
func (uc UsersController) list(request *restful.Request,
	response *restful.Response) {
	curUser := GetCurrentUser(request, response)
	if curUser == nil {
		Unauthenticated(request, response)
		return
	}
	var limit int
	var pageNum int
	limitString := request.QueryParameter("numPerPage")
	if limitString == "" {
		limit = 0
	} else {
		ln, err := strconv.Atoi(limitString)
		if err != nil {
			log.Printf("Error: %v", err)
			WriteIllegalRequestError(response)
			return
		}
		limit = ln
	}
	pageNumString := request.QueryParameter("pageNum")
	if pageNumString == "" {
		pageNum = 1
	} else {
		if ln, err := strconv.Atoi(pageNumString); err != nil {
			log.Printf("Error: %v", err)
			WriteIllegalRequestError(response)
		} else {
			pageNum = ln
		}
	}
	ulr := UserListQueryResponse{}
	forResource := request.QueryParameter("forResource")
	var err error
	if forResource != "" {
		//Make sure the user is an admin for the given resource
		if !util.HasRole(curUser.User.Roles, AdminRole(forResource)) &&
			!util.HasRole(curUser.User.Roles, AdminRole(MainDbName())) {
			WriteError(NotAdminError(), response)
			return
		}
		rolesArray := []string{AdminRole(forResource),
			WriteRole(forResource), ReadRole(forResource)}
		err = new(UserManager).GetUserListForRole(
			pageNum, limit, rolesArray, &ulr, curUser)
	} else {
		err = new(UserManager).GetUserList(pageNum, limit, &ulr, curUser)
	}
	if err != nil {
		WriteError(err, response)
		return
	}
	uir := uc.genUserListResponse(curUser, &ulr)
	SetAuth(response, curUser.Auth)
	response.WriteEntity(uir)
}
예제 #5
0
//Create usual links for an index
func GenIndexLinks(userRoles []string, dbName string, uri string) HatLinks {
	links := HatLinks{}
	admin := util.HasRole(userRoles, AdminRole(dbName))
	write := util.HasRole(userRoles, WriteRole(dbName))
	//Generate the self link
	links.Self = &HatLink{Href: uri, Method: "GET"}
	if admin || write {
		links.Create = &HatLink{Href: uri, Method: "POST"}
	}
	return links
}
예제 #6
0
//Create the basic CRUD links for a resource record
func GenRecordLinks(userRoles []string, dbName string, uri string) HatLinks {
	links := HatLinks{}
	//Admin can be a resource admin OR a site admin/master
	admin := util.HasRole(userRoles, AdminRole(dbName)) ||
		util.HasRole(userRoles, AdminRole(MainDbName())) ||
		util.HasRole(userRoles, MasterRole())
	write := util.HasRole(userRoles, WriteRole(dbName))
	//Generate the self link
	links.Self = &HatLink{Href: uri, Method: "GET"}
	if admin || write {
		links.Update = &HatLink{Href: uri, Method: "PUT"}
		links.Delete = &HatLink{Href: uri, Method: "DELETE"}
	}
	return links
}
예제 #7
0
//Get a user
func (um *UserManager) Read(id string, user *User,
	curUser *CurrentUserInfo) (string, error) {
	//Who am I?
	theUser := curUser.User
	readUser := User{}
	if util.HasRole(theUser.Roles, AdminRole(MainDbName())) {
		//This is an admin
		userDb := Connection.SelectDB(UserDbName, AdminAuth)
		rev, err := userDb.Read(UserPrefix+id, &readUser, nil)
		if err != nil {
			return "", err
		} else {
			*user = readUser
			return rev, nil
		}
	} else {
		userDb := Connection.SelectDB(UserDbName, curUser.Auth)
		if rev, err := userDb.Read(UserPrefix+id, &readUser, nil); err != nil {
			return "", err
		} else {
			*user = readUser
			return rev, nil
		}
	}
}
예제 #8
0
//Generates the Links for a UserAvatar Record Response
func (ac AvatarController) genAvatarRecordLinks(user *User,
	userId string, uri string) avatarLinks {
	links := avatarLinks{}
	userRoles := user.Roles
	admin := util.HasRole(userRoles, AdminRole(MainDbName())) ||
		util.HasRole(userRoles, MasterRole())
	write := user.UserName == userId
	links.Self = &HatLink{Href: uri, Method: "GET"}
	links.GetLargeAvatar = &HatLink{Href: uri + "/image", Method: "GET"}
	links.GetThumbnailAvatar = &HatLink{Href: uri + "/thumbnail", Method: "GET"}
	if admin || write {
		links.Update = &HatLink{Href: uri, Method: "PUT"}
		links.Delete = &HatLink{Href: uri, Method: "DELETE"}
		links.SaveImage = &HatLink{Href: uri + "/image", Method: "PUT"}
	}
	return links
}
예제 #9
0
func (fc FileController) genFileRecordLinks(userRoles []string,
	wikiDb string, uri string) fileLinks {
	links := fileLinks{}
	admin := util.HasRole(userRoles, AdminRole(wikiDb))
	read := util.HasRole(userRoles, ReadRole(wikiDb))
	write := util.HasRole(userRoles, WriteRole(wikiDb))
	if admin || read || write {
		links.Self = &HatLink{Href: uri, Method: "GET"}
		links.GetAttachment = &HatLink{Href: uri + "/content", Method: "GET"}
	}
	if admin || write {
		links.Update = &HatLink{Href: uri, Method: "PUT"}
		links.Delete = &HatLink{Href: uri, Method: "DELETE"}
		links.SaveAttachment = &HatLink{Href: uri + "/content", Method: "PUT"}
	}
	return links
}
예제 #10
0
//Create a new wiki
func (wm *WikiManager) Create(id string, wr *WikiRecord,
	curUser *CurrentUserInfo) (string, error) {
	auth := curUser.Auth
	theUser := curUser.User
	//Verify user is authorized to create wikis
	mainDb := MainDbName()
	if !util.HasRole(theUser.Roles, AdminRole(mainDb)) &&
		!util.HasRole(theUser.Roles, WriteRole(mainDb)) {
		return "", NotAdminError()
	}
	owner := theUser.UserName
	//Add an entry for this wiki to the Main db
	wr.Id = id
	wr.Slug = slugification.Slugify(wr.Name)
	wr.CreatedAt = time.Now().UTC()
	wr.ModifiedAt = time.Now().UTC()
	wr.Type = "wiki_record"
	if err := wr.Validate(); err != nil {
		return "", err
	}
	cDb := Connection.SelectDB(mainDb, auth)
	log.Printf("Adding wiki entry %v to db %v", id, mainDb)
	rev, err := cDb.Save(&wr, id, "")
	//Check for duplicate slugs
	err = wm.checkForDuplicateSlug(wr.Slug)
	if err != nil {
		//Delete the wiki record we just created
		cDb.Delete(id, rev)
		return "", err
	}
	//Create the Wiki
	log.Printf("Creating Wiki: %v", id)
	err = wikit.CreateWiki(Connection, AdminAuth, owner, WikiDbName(id))
	if err != nil {
		//Delete the wiki record from maindb
		cDb.Delete(id, rev)
		return "", err
	}

	//Set Guest Acess
	if err := wm.setGuestAccess(id, wr, auth); err != nil {
		return rev, err
	}
	//wr.Id = id
	return rev, nil
}
예제 #11
0
//Update a user
func (um *UserManager) Update(id string, rev string, updatedUser *User,
	curUser *CurrentUserInfo) (string, error) {
	//Who am I?
	theUser := curUser.User
	var auth couchdb.Auth
	//make sure Id matches the user object
	if id != updatedUser.UserName {
		return "", BadRequestError()
	}
	//check for admin
	if util.HasRole(theUser.Roles, AdminRole(MainDbName())) ||
		util.HasRole(theUser.Roles, MasterRole()) {
		auth = AdminAuth
	} else {
		auth = curUser.Auth
	}
	userDb := Connection.SelectDB(UserDbName, auth)
	//pull the user record
	namestring := UserPrefix + id
	//readUser := FullUserRecord{}
	var userData interface{}
	_, err := userDb.Read(namestring, &userData, nil)
	if err != nil {
		return "", err
	}
	readUser := userData.(map[string]interface{})
	//Update the user parameters of the read user
	//We do this instead of just pushing the updated user to CouchDB,
	//because the updated user doesn't contain password information,
	//and we don't want to wipe away the password.
	nowTime := time.Now().UTC()
	readUser["modifiedAt"] = nowTime
	readUser["userPublic"] = updatedUser.Public
	readUser["userName"] = updatedUser.UserName
	readUser["password_reset"] = updatedUser.PassResetToken
	//And save the updated user
	uRev, err := userDb.Save(&readUser, namestring, rev)
	if err != nil {
		return "", err
	}
	//Censor the password
	//updatedUser.Password = ""
	return uRev, nil

}
예제 #12
0
//Delete a User Avatar Record
func (uam *UserAvatarManager) Delete(id string, curUser *CurrentUserInfo) (string, error) {
	theUser := curUser.User
	var auth couchdb.Auth
	if util.HasRole(theUser.Roles, AdminRole(MainDbName())) ||
		util.HasRole(theUser.Roles, MasterRole()) {
		auth = AdminAuth
	} else {
		auth = curUser.Auth
	}
	avatarDb := Connection.SelectDB(AvatarDbName(), auth)
	//Fetch the record
	avatarRecord := new(UserAvatar)
	rev, err := avatarDb.Read(id, avatarRecord, nil)
	if err != nil {
		return "", err
	}
	return avatarDb.Delete(id, rev)
}
예제 #13
0
//Save User Avatar Record
func (uam *UserAvatarManager) Save(id string, rev string,
	avatar *UserAvatar, curUser *CurrentUserInfo) (string, error) {
	nowTime := time.Now().UTC()
	if rev == "" {
		avatar.CreatedAt = nowTime
	}
	avatar.ModifiedAt = nowTime
	var auth couchdb.Auth
	//check for admin
	if util.HasRole(curUser.Roles, AdminRole(MainDbName())) ||
		util.HasRole(curUser.Roles, MasterRole()) {
		auth = AdminAuth
	} else {
		auth = curUser.Auth
	}
	avatarDb := Connection.SelectDB(AvatarDbName(), auth)
	return avatarDb.Save(avatar, id, rev)
}
예제 #14
0
// Change a user's password
func (um *UserManager) ChangePassword(id string, rev string,
	cpr *ChangePasswordRequest, curUser *CurrentUserInfo) (string, error) {
	theUser := curUser.User
	var auth couchdb.Auth
	//check for admin
	isAdmin := util.HasRole(theUser.Roles, AdminRole(MainDbName())) ||
		util.HasRole(theUser.Roles, MasterRole())

	if isAdmin {
		auth = AdminAuth
	} else {
		auth = curUser.Auth
	}
	//Must we validate the old password?
	if !isAdmin || (isAdmin && theUser.UserName == id) {
		//yes, let's use the old password to do this thing
		auth = &couchdb.BasicAuth{Username: id, Password: cpr.OldPassword}
	}
	//validate password
	err := um.validatePassword(cpr.NewPassword)
	if err != nil {
		return "", err
	}
	userDb := Connection.SelectDB(UserDbName, auth)
	//pull the user record
	namestring := UserPrefix + id
	var userData interface{}
	_, err = userDb.Read(namestring, &userData, nil)
	if err != nil {
		return "", err
	}
	readUser := userData.(map[string]interface{})
	//Update JUST the password (and modified time)
	nowTime := time.Now().UTC()
	readUser["modifiedAt"] = nowTime
	readUser["password"] = cpr.NewPassword
	//Save the updated user
	uRev, err := userDb.Save(&readUser, namestring, rev)
	if err != nil {
		return "", err
	}
	return uRev, nil

}
예제 #15
0
//Grant a role to a user
func (um *UserManager) GrantRole(id string,
	grantRequest *RoleRequest,
	curUser *CurrentUserInfo) (string, error) {

	newRole := grantRequest.roleString()
	//Who am I?
	theUser := curUser.User
	//Make sure user is an admin of the resource being requested
	resourceDbName := resourceDbName(grantRequest)
	if !util.HasRole(theUser.Roles, AdminRole(MainDbName())) &&
		!util.HasRole(theUser.Roles, MasterRole()) &&
		!util.HasRole(theUser.Roles, AdminRole(resourceDbName)) {
		//Not an admin
		return "", NotAdminError()
	}
	//Are we trying to grant the site admin role?
	//If so, curUser must be a master user
	if newRole == AdminRole(MainDbName()) &&
		!util.HasRole(theUser.Roles, MasterRole()) {
		return "", NotAdminError()

	}
	//Fetch the user
	userDb := Connection.SelectDB(UserDbName, AdminAuth)
	readUser := new(User)
	rev, err := userDb.Read(UserPrefix+id, readUser, nil)
	if err != nil {
		return "", err
	}
	//validate the role request
	if grantRequest.validate() == false {
		return "", BadRequestError()
	}
	//All is well, grant the role
	rev, err = Connection.GrantRole(id, newRole, AdminAuth)
	if err != nil {
		return "", err
	}
	return rev, nil
}
예제 #16
0
//Delete a user
func (um *UserManager) Delete(id string,
	curUser *CurrentUserInfo) (string, error) {
	//Who am I?
	theUser := curUser.User
	//check for admin
	if !util.HasRole(theUser.Roles, AdminRole(MainDbName())) {
		return "", NotAdminError()
	}
	//pull the user record
	namestring := UserPrefix + id
	readUser := new(User)
	rev, err := um.Read(id, readUser, curUser)
	if err != nil {
		return "", err
	}
	//Do the delete
	theDb := Connection.SelectDB(UserDbName, AdminAuth)
	return theDb.Delete(namestring, rev)
}
예제 #17
0
func (uc UsersController) genUserRecordLinks(userRoles []string,
	userId string, curUserId string, uri string) HatLinks {
	links := HatLinks{}
	dbName := MainDbName()
	admin := util.HasRole(userRoles, AdminRole(dbName))
	//Write := util.HasRole(userRoles, WriteRole(dbName))
	self := func() bool {
		if curUserId == userId {
			return true
		} else {
			return false
		}
	}()
	links.Self = &HatLink{Href: uri, Method: "GET"}
	if admin || self {
		links.Update = &HatLink{Href: uri, Method: "PUT"}
	}
	return links
}
예제 #18
0
//Delete a wiki record and the associated wiki database
func (wm *WikiManager) Delete(id string, curUser *CurrentUserInfo) error {
	//Who am I?
	theUser := curUser.User
	auth := curUser.Auth

	mainDb := MainDbName()
	cDb := Connection.SelectDB(mainDb, auth)
	//Check for admin
	if !util.HasRole(theUser.Roles, AdminRole(mainDb)) {
		return NotAdminError()
	}
	//Fetch the wiki record
	wikiRecord := new(WikiRecord)
	_, err := cDb.Read(id, wikiRecord, nil)
	if err != nil {
		return err
	}
	/*if wikiRecord.Id != id {
		return errors.New("WikiRecord doesn't match Database Id")
	}*/
	err = DeleteDb(WikiDbName(id))
	if err != nil {
		return err
	}
	delFunc := func() error {
		rev, err := cDb.Read(id, wikiRecord, nil)
		_, err = cDb.Delete(id, rev)
		if err != nil {
			return err
		} else {
			return nil
		}
	}
	err = util.Retry(3, delFunc)
	if err != nil {
		return err
	}
	return nil
}
예제 #19
0
func TestUsers(t *testing.T) {
	setup()
	defer services.DeleteDb(services.MainDb)
	smithUser := func() *entities.CurrentUserInfo {
		smithAuth := &couchdb.BasicAuth{Username: "******", Password: "******"}
		smith, err := services.GetUserFromAuth(smithAuth)
		if err != nil {
			t.Error(err)
			return &entities.CurrentUserInfo{}
		}
		return &entities.CurrentUserInfo{
			Auth: smithAuth,
			User: smith,
		}
	}
	//after test cleanup
	defer func() {
		getSmithUser := func() *entities.CurrentUserInfo {
			return smithUser()
		}
		um.Delete("Steven.Smith", getSmithUser())
	}()
	Convey("Given a new account registration", t, func() {
		user := entities.User{
			UserName: "******",
			Password: "******",
		}
		registration := user_service.Registration{
			NewUser: user,
		}
		Convey("When the new user is registered", func() {
			rev, err := um.SetUp(&registration)
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
				t.Logf("New user revision: %v", rev)
			})
		})
		Convey("When a new user for the account is created", func() {
			subUser := entities.User{
				UserName: "******",
				Password: "******",
				Public: entities.UserPublic{
					LastName:  "Smith",
					FirstName: "Sally",
				},
			}
			rev, err := um.Create(&subUser, smithUser())
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			Convey("The user should have the appropriate roles", func() {
				So(util.HasRole(subUser.Roles, "all_users"), ShouldEqual, true)
			})
		})
		Convey("When the user is updated", func() {
			auth := couchdb.BasicAuth{Username: "******", Password: "******"}
			updateUser := entities.User{}
			rev, err := um.Read("Sally.Smith", &updateUser, smithUser())
			So(err, ShouldBeNil)
			curUser := entities.CurrentUserInfo{
				User: &updateUser,
				Auth: &auth,
			}

			updateUser.Public.MiddleName = "Marie"
			rev, err = um.Update("Sally.Smith", rev, &updateUser, &curUser)
			Convey("Error should be nil and the revision should be set", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			rev, err = um.Read("Sally.Smith", &updateUser, smithUser())
			Convey("The user's password should still be valid", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})

		})
		Convey("When the user's password is changed", func() {
			auth := couchdb.BasicAuth{Username: "******", Password: "******"}
			updateUser := entities.User{}
			rev, err := um.Read("Sally.Smith", &updateUser, smithUser())
			So(err, ShouldBeNil)
			curUser := entities.CurrentUserInfo{
				User: &updateUser,
				Auth: &auth,
			}
			newPassword := "******"
			cpr := user_service.ChangePasswordRequest{
				NewPassword: newPassword,
				OldPassword: "******",
			}
			rev, err = um.ChangePassword("Sally.Smith", rev, &cpr, &curUser)
			Convey("Error should be nil and the revision should be set", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			rev, err = um.Read("Sally.Smith", &updateUser, &curUser)
			Convey("Old password should NOT work", func() {
				So(err, ShouldNotBeNil)
			})
			curUser.Auth = &couchdb.BasicAuth{Username: "******", Password: "******"}
			rev, err = um.Read("Sally.Smith", &updateUser, &curUser)
			Convey("New password should work", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})

		})
		Convey("When a user is granted a role", func() {
			curUser := smithUser()
			roleRequest := user_service.RoleRequest{
				ResourceType: "main",
				ResourceId:   "",
				AccessType:   "write",
			}
			rev, err := um.GrantRole("Sally.Smith", &roleRequest, curUser)
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			Convey("User should have her new role", func() {
				readUser := new(entities.User)
				_, err := um.Read("Sally.Smith", readUser, smithUser())
				So(err, ShouldBeNil)
				t.Logf("Sally's Record: %v", readUser)
				searchRole := "main_" + ":write"
				searchRoleFound := false
				if readUser.Roles[2] == searchRole {
					searchRoleFound = true
				}
				So(searchRoleFound, ShouldEqual, true)
			})

		})
		Convey("When a user has a role revoked", func() {
			curUser := smithUser()
			roleRequest := user_service.RoleRequest{
				ResourceType: "main",
				ResourceId:   "",
				AccessType:   "write",
			}
			rev, err := um.RevokeRole("Sally.Smith", &roleRequest, curUser)
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			Convey("User should no longer have her role", func() {
				readUser := new(entities.User)
				_, err := um.Read("Sally.Smith", readUser, smithUser())
				So(err, ShouldBeNil)
				searchRole := "main" + ":write"
				searchRoleFound := false
				if len(readUser.Roles) > 1 && readUser.Roles[1] == searchRole {
					searchRoleFound = true
				}
				So(searchRoleFound, ShouldEqual, false)

			})
		})
		Convey("When the user list is requested", func() {
			userList := user_service.UserListQueryResponse{}
			err := um.GetUserList(1, 5, &userList, smithUser())
			Convey("Error should be nil and we should have some results", func() {
				So(err, ShouldBeNil)
				So(len(userList.Rows) >= 2, ShouldBeTrue)
				t.Logf("UserListResponse: %v", userList)
			})
		})
		Convey("When the user is read", func() {
			readUser := entities.User{}
			rev, err := um.Read(user.UserName, &readUser, smithUser())
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
			})
			Convey("The user data should be set", func() {
				So(readUser.CreatedAt, ShouldNotBeNil)
				So(readUser.UserName, ShouldEqual, "Steven.Smith")
			})
		})
		Convey("When the user by roles list is requested", func() {
			userList := user_service.UserListQueryResponse{}
			err := um.GetUserListForRole(1, 5, []string{"all_users"},
				&userList, smithUser())
			Convey("The error should be nil and we should have some results", func() {
				So(err, ShouldBeNil)
				t.Logf("Response: %v", userList)
			})
		})
		Convey("When a user password reset is requested", func() {
			err := um.RequestPasswordReset("Steven.Smith")
			Convey("The error should indicate no notifcation services are present", func() {
				So(err.Error(), ShouldEqual, "No notifications services listed!")
			})
		})
		Convey("When the user is deleted", func() {
			rev, err := um.Delete("Sally.Smith", smithUser())
			Convey("The revision should be set and the error should be nil", func() {
				So(err, ShouldBeNil)
				So(rev, ShouldNotEqual, "")
				t.Logf("Deleted User rev: %v", rev)
			})
		})
	})
}