package e2e

import (
	"encoding/json"
	"fmt"
	"net/url"
	"strings"

	"github.com/duke-git/lancet/v2/slice"
)

func ExecCentralUserCase() {
	//Central_GetUserProfileV2()
	//Central_UpdateUserProfile()

	Central_InviteUserToOrg()
	Central_InviteUserToOrg_ParamInvalid()
	Central_InviteUserToOrg_EmailAlreadyInOrg()
	//Central_ListOrgUsers()
	//Central_UpdateOrgUserRole()
	//Central_RemoveUserFromOrg()
	//
	Central_InviteUserToProject()
	//Central_ListProjectUsers()
	Central_InviteUserToProject_ParamInvalid()
	Central_InviteUserToProject_EmailAlreadyInProject()
	Central_InviteUserToProject_EmailInOrgNotInProject()
	//Central_UpdateProjectUserRole()
	//Central_RemoveUserFromProject()
	//
	//Central_ListRolesByUserID()
	//Central_ListUsersByScope()
	//
	//Central_OneConsole_ListOrgLevelConsoleUsersByOrgOwnerWithEmailFilter()
	//Central_OneConsole_ListConsoleUsers_NoFilter()
	//Central_OneConsole_ListConsoleUsers_WithRoleFilter()
	//Console_OneConsole_AssignConsoleUserRole()
	//Console_OneConsole_AssignConsoleUserRole_WithProjectRoles()
	//Console_OneConsole_AssignConsoleUserRole_WithProjectAndClusterRoles()
	//Console_OneConsole_EditConsoleUserRole()
	//Console_OneConsole_EditConsoleUserRole_OnlyOrgRole()
	//Console_OneConsole_CheckEmailAlreadyHasOrgRole()
	//Console_OneConsole_CheckEmailAlreadyHasOrgRole_AllUnknown()
	//
	//Central_CheckUserLoginStateNotRevoked()
	//Central_RevokeUserLoginStateByLogoutAllDevice()
	//Central_RevokeUserLoginStateByChangePasswordCallback_TokenInvalid()
}

func Central_GetUserProfileV2() {
	url := DevConsoleHost + "/api/v1/user/me"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "GetUserProfileV2", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_UpdateUserProfile() {
	updateUrl := DevConsoleHost + "/api/v1/orgs/1440002/users/me"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"first_name": "lq",
				"last_name": "z",
				"phone_number": "135%s"
			}`, CurDateStr())
	code, data, err := RestyExec("PUT", updateUrl, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "UpdateUserProfile", CaseDetail{
		Url:       updateUrl,
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})

}

func Central_InviteUserToOrg() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/users"
	email := fmt.Sprintf("teste2e%s@pingcap.com", CurTimeStr())
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "org:owner"
			}`, email)
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}

	listUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s", email)
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = inviteErr.Error()
	}

	Pass := false
	if listCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listData), users)
		if err == nil {
			if users.Total == 1 &&
				users.Items[0].Email == email &&
				users.Items[0].RbacRole == "org:owner" &&
				strings.ToUpper(users.Items[0].Status) == "PENDING" {
				Pass = true
			}
		}
	}
	SaveCase("Central_User", "InviteUserToOrg", CaseDetail{
		Url:       inviteUrl,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      Pass,
		RspCode:   inviteCode,
		RspData:   inviteData,
		Extra: map[string]interface{}{
			"list_url":  listUrl,
			"list_code": listCode,
			"list_data": listData,
		},
	})

}

type Users struct {
	Total int32   `json:"total,omitempty"`
	Items []*User `json:"items,omitempty"`
}

type User struct {
	Id       string `json:"id,omitempty"`
	Email    string ` json:"email,omitempty"`
	Name     string `json:"name,omitempty"`
	Status   string `json:"status,omitempty"`
	Role     string `json:"role,omitempty"`
	RbacRole string `json:"rbac_role,omitempty"`
}

func Central_InviteUserToOrg_EmailAlreadyInOrg() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/users"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "org:owner"
			}`, "liqing.zhu_20251021111228@pingcap.com")
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}
	SaveCase("Central_User", "InviteUserToOrg_EmailAlreadyInOrg", CaseDetail{
		Url:       inviteUrl,
		ReqHeader: header,
		ReqBody:   "",
		Pass:      inviteCode == 400,
		RspCode:   inviteCode,
		RspData:   inviteData,
	})
}

func Central_InviteUserToOrg_ParamInvalid() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/users"
	email := fmt.Sprintf("teste2e%s@pingcap.com", CurTimeStr())
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "project:owner"
			}`, email)
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}
	SaveCase("Central_User", "InviteUserToOrg_ParamInvalid", CaseDetail{
		Url:       inviteUrl,
		ReqHeader: header,
		ReqBody:   "",
		Pass:      inviteCode == 400,
		RspCode:   inviteCode,
		RspData:   inviteData,
	})
}

func Central_ListOrgUsers() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/users?page=1&per_page=2"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "ListOrgUsers", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})

}

func Central_UpdateOrgUserRole() {
	Pass := false

	listUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s&per_page=2", "teste2e")
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var user *User
	if listCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listData), users)
		if err == nil && len(users.Items) > 0 {
			user = users.Items[0]
		}
	}
	var updateUrl, updateBody, updateData string
	var updateCode int
	var updateErr error
	var secondListUrl, secondListData string
	var secondListCode int
	if user != nil {
		updateUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users/%s", user.Id)
		updateBody = `{
			"rbac_role": "org:member"
		}`
		updateCode, updateData, updateErr = RestyExec("PUT", updateUrl, header, updateBody)
		if updateErr != nil {
			updateCode = 0
			updateData = updateErr.Error()
		}
		if updateCode == 200 {
			secondListUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s", user.Email)
			secondListCode, secondListData, listErr = RestyExec("GET", secondListUrl, header, "")
			if listErr != nil {
				secondListCode = 0
				secondListData = listErr.Error()
			}
			if secondListCode == 200 {
				users := &Users{}
				err := json.Unmarshal([]byte(secondListData), users)
				if err == nil {
					if users.Total == 1 &&
						users.Items[0].Email == user.Email &&
						users.Items[0].RbacRole == "org:member" {
						Pass = true
					}
				}
			}

		}
	}

	SaveCase("Central_User", "UpdateOrgUserRole", CaseDetail{
		Url:       updateUrl,
		Method:    "PUT",
		ReqHeader: header,
		ReqBody:   updateBody,
		Pass:      Pass,
		RspCode:   updateCode,
		RspData:   updateData,
		Extra: map[string]interface{}{
			"list_url":         listUrl,
			"list_code":        listCode,
			"list_data":        listData,
			"second_list_url":  secondListUrl,
			"second_list_code": secondListCode,
			"second_list_data": secondListData,
		},
	})
}

func Central_RemoveUserFromOrg() {
	Pass := false

	listUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s&per_page=2", "teste2e")
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var user *User
	if listCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listData), users)
		if err == nil && len(users.Items) > 0 {
			user = users.Items[0]
		}
	}

	var deleteUrl, deleteData string
	var deleteCode int
	var deleteErr error
	var secondListUrl, secondListData string
	var secondListCode int
	if user != nil {
		deleteUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users/%s", user.Id)
		deleteCode, deleteData, deleteErr = RestyExec("DELETE", deleteUrl, header, "")
		if deleteErr != nil {
			deleteCode = 0
			deleteData = deleteErr.Error()
		}
		if deleteCode == 200 {
			secondListUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s", user.Email)
			secondListCode, secondListData, listErr = RestyExec("GET", secondListUrl, header, "")
			if listErr != nil {
				secondListCode = 0
				secondListData = listErr.Error()
			}
			if secondListCode == 200 {
				users := &Users{}
				err := json.Unmarshal([]byte(secondListData), users)
				if err == nil {
					if users.Total == 0 && len(users.Items) == 0 {
						Pass = true
					}
				}
			}
		}
	}

	SaveCase("Central_User", "RemoveUserFromOrg", CaseDetail{
		Url:       deleteUrl,
		Method:    "DELETE",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      Pass,
		RspCode:   deleteCode,
		RspData:   deleteData,
		Extra: map[string]interface{}{
			"list_url":         listUrl,
			"list_code":        listCode,
			"list_data":        listData,
			"second_list_url":  secondListUrl,
			"second_list_code": secondListCode,
			"second_list_data": secondListData,
		},
	})

}

func Central_InviteUserToProject() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects/3199935/users"
	email := fmt.Sprintf("teste2e%s@pingcap.com", CurTimeStr())
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "project:owner"
			}`, email)
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}

	listProjectUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users?email=%s", email)
	listProjectCode, listProjectData, listProjectErr := RestyExec("GET", listProjectUrl, header, "")
	if listProjectErr != nil {
		listProjectCode = 0
		listProjectData = listProjectErr.Error()
	}

	listOrgUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/users?email=%s", email)
	listOrgCode, listOrgData, listOrgErr := RestyExec("GET", listOrgUrl, header, "")
	if listOrgErr != nil {
		listOrgCode = 0
		listOrgData = listOrgErr.Error()
	}

	Pass := false
	if listProjectCode == 200 && listOrgCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listProjectData), users)
		if err == nil {
			if users.Total == 1 && users.Items[0].Email == email && users.Items[0].RbacRole == "project:owner" && strings.ToUpper(users.Items[0].Status) == "PENDING" {
				orgUsers := &Users{}
				err := json.Unmarshal([]byte(listOrgData), orgUsers)
				if err == nil {
					if orgUsers.Total == 1 && orgUsers.Items[0].Email == email && orgUsers.Items[0].RbacRole == "org:member" {
						Pass = true
					}
				}

			}
		}
	}
	SaveCase("Central_User", "InviteUserToProject", CaseDetail{
		Url:       inviteUrl,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      Pass,
		RspCode:   inviteCode,
		RspData:   inviteData,
		Extra: map[string]interface{}{
			"list_project_user_url":  listProjectUrl,
			"list_project_user_code": listProjectCode,
			"list_project_user_data": listProjectData,
			"list_org_user_url":      listOrgUrl,
			"list_org_user_code":     listOrgCode,
			"list_org_user_data":     listOrgData,
		},
	})
}

func Central_ListProjectUsers() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/projects/3199935/users?page=1&per_page=2&email=teste2e"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	Pass := false
	if code == 200 {
		Pass = true
		users := &Users{}
		err := json.Unmarshal([]byte(data), users)
		if err == nil {
			for _, u := range users.Items {
				if !strings.HasPrefix(u.Email, "teste2e") {
					Pass = false
				}
				if !strings.HasPrefix(u.RbacRole, "project:") {
					Pass = false
				}
			}

		}
	}

	SaveCase("Central_User", "ListProjectUsers", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      Pass,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_InviteUserToProject_ParamInvalid() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects/3199935/users"
	email := fmt.Sprintf("teste2e%s@pingcap.com", CurTimeStr())
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "org:owner"
			}`, email)
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}

	SaveCase("Central_User", "InviteUserToProject_ParamInvalid", CaseDetail{
		Url:       inviteUrl,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      inviteCode == 400,
		RspCode:   inviteCode,
		RspData:   inviteData,
	})

}

func Central_InviteUserToProject_EmailAlreadyInProject() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects/3199935/users"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "project:owner"
			}`, "liqing.zhu_20251021111228@pingcap.com")
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}

	SaveCase("Central_User", "InviteUserToProject_EmailAlreadyInProject", CaseDetail{
		Url:       inviteUrl,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      inviteCode == 400,
		RspCode:   inviteCode,
		RspData:   inviteData,
	})

}

func Central_InviteUserToProject_EmailInOrgNotInProject() {
	inviteUrl := DevConsoleHost + "/api/v1/orgs/1440002/projects/3199935/users"
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	body := fmt.Sprintf(`{
				"email": "%s",
				"rbac_role": "project:owner"
			}`, "liqing.zhu+6@pingcap.com")
	inviteCode, inviteData, inviteErr := RestyExec("POST", inviteUrl, header, body)
	if inviteErr != nil {
		inviteCode = 0
		inviteData = inviteErr.Error()
	}

	SaveCase("Central_User", "InviteUserToProject_ParamInvalid", CaseDetail{
		Url:       inviteUrl,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      inviteCode == 400,
		RspCode:   inviteCode,
		RspData:   inviteData,
	})

}

func Central_UpdateProjectUserRole() {
	Pass := false

	listUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users?email=%s&per_page=2", "teste2e")
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var user *User
	if listCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listData), users)
		if err == nil && len(users.Items) > 0 {
			user = users.Items[0]
		}
	}
	var updateUrl, updateBody, updateData string
	var updateCode int
	var updateErr error
	var secondListUrl, secondListData string
	var secondListCode int
	if user != nil {
		updateUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users/%s", user.Id)
		updateBody = `{
			"rbac_role": "project:dev"
		}`
		updateCode, updateData, updateErr = RestyExec("PATCH", updateUrl, header, updateBody)
		if updateErr != nil {
			updateCode = 0
			updateData = updateErr.Error()
		}
		if updateCode == 200 {
			secondListUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users?email=%s", user.Email)
			secondListCode, secondListData, listErr = RestyExec("GET", secondListUrl, header, "")
			if listErr != nil {
				secondListCode = 0
				secondListData = listErr.Error()
			}
			if secondListCode == 200 {
				users := &Users{}
				err := json.Unmarshal([]byte(secondListData), users)
				if err == nil {
					if users.Total == 1 &&
						users.Items[0].Email == user.Email &&
						users.Items[0].RbacRole == "project:dev" {
						Pass = true
					}
				}
			}

		}
	}

	SaveCase("Central_User", "UpdateProjectUserRole", CaseDetail{
		Url:       updateUrl,
		Method:    "PATCH",
		ReqHeader: header,
		ReqBody:   updateBody,
		Pass:      Pass,
		RspCode:   updateCode,
		RspData:   updateData,
		Extra: map[string]interface{}{
			"list_url":         listUrl,
			"list_code":        listCode,
			"list_data":        listData,
			"second_list_url":  secondListUrl,
			"second_list_code": secondListCode,
			"second_list_data": secondListData,
		},
	})
}

func Central_RemoveUserFromProject() {
	Pass := false

	listUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users?email=%s&per_page=2", "teste2e")
	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization
	listCode, listData, listErr := RestyExec("GET", listUrl, header, "")
	if listErr != nil {
		listCode = 0
		listData = listErr.Error()
	}
	var user *User
	if listCode == 200 {
		users := &Users{}
		err := json.Unmarshal([]byte(listData), users)
		if err == nil && len(users.Items) > 0 {
			user = users.Items[0]
		}
	}

	var deleteUrl, deleteData string
	var deleteCode int
	var deleteErr error
	var secondListUrl, secondListData string
	var secondListCode int
	if user != nil {
		deleteUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users/%s", user.Id)
		deleteCode, deleteData, deleteErr = RestyExec("DELETE", deleteUrl, header, "")
		if deleteErr != nil {
			deleteCode = 0
			deleteData = deleteErr.Error()
		}
		if deleteCode == 200 {
			secondListUrl = DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/projects/3199935/users?email=%s", user.Email)
			secondListCode, secondListData, listErr = RestyExec("GET", secondListUrl, header, "")
			if listErr != nil {
				secondListCode = 0
				secondListData = listErr.Error()
			}
			if secondListCode == 200 {
				users := &Users{}
				err := json.Unmarshal([]byte(secondListData), users)
				if err == nil {
					if users.Total == 0 && len(users.Items) == 0 {
						Pass = true
					}
				}
			}
		}
	}

	SaveCase("Central_User", "RemoveUserFromProject", CaseDetail{
		Url:       deleteUrl,
		Method:    "DELETE",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      Pass,
		RspCode:   deleteCode,
		RspData:   deleteData,
		Extra: map[string]interface{}{
			"list_url":         listUrl,
			"list_code":        listCode,
			"list_data":        listData,
			"second_list_url":  secondListUrl,
			"second_list_code": secondListCode,
			"second_list_data": secondListData,
		},
	})
}

func Central_ListRolesByUserID() {
	url := DevConsoleHost + "/api/v1/user-roles?user_id=71002&scope_type=ORG"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	pass := false
	if code == 200 {
		var rsp = &ListRolesByUserIDRsp{}
		err := json.Unmarshal([]byte(data), rsp)
		if err == nil {
			for _, org := range rsp.Items {
				if org.ScopeType == "ORG" && org.ScopeId == "1440002" {
					pass = true
					break
				}
			}
		}
	}

	SaveCase("Central_User", "ListRolesByUserID", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

type ListRolesByUserIDRsp struct {
	Total int32       `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
	Items []*UserRole `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
}

type UserRole struct {
	UserId          string `protobuf:"varint,1,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
	ScopeType       string `protobuf:"bytes,2,opt,name=scope_type,json=scopeType,proto3" json:"scope_type,omitempty"`
	ScopeId         string `protobuf:"varint,3,opt,name=scope_id,json=scopeId,proto3" json:"scope_id,omitempty"`
	RoleName        string `protobuf:"bytes,4,opt,name=role_name,json=roleName,proto3" json:"role_name,omitempty"`
	RoleDisplayName string `protobuf:"bytes,5,opt,name=role_display_name,json=roleDisplayName,proto3" json:"role_display_name,omitempty"`
	RoleDesc        string `protobuf:"bytes,6,opt,name=role_desc,json=roleDesc,proto3" json:"role_desc,omitempty"`
	RoleId          string `protobuf:"varint,7,opt,name=role_id,json=roleId,proto3" json:"role_id,omitempty"`
	RealBinding     bool   `protobuf:"varint,8,opt,name=real_binding,json=realBinding,proto3" json:"real_binding,omitempty"`
}

func Central_ListUsersByScope() {
	url := DevConsoleHost + "/api/v1/scope-users?scope_type=ORG&scope_id=1440002"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	pass := false
	if code == 200 {
		var rsp = &Users{}
		err := json.Unmarshal([]byte(data), rsp)
		if err == nil {
			for _, user := range rsp.Items {
				if user.Id == "71002" && user.Status == "active" {
					pass = true
					break
				}
			}
		}
	}

	SaveCase("Central_User", "ListUsersByScope", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_OneConsole_ListOrgLevelConsoleUsersByOrgOwnerWithEmailFilter() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-users?scope_type=ORG&&per_page=5&email=qing"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	pass := false
	if code == 200 {
		var rsp = &ListConsoleUsersResp{}
		err := json.Unmarshal([]byte(data), rsp)
		if err == nil && len(rsp.Items) <= 5 {
			pass = true
			for _, u := range rsp.Items {
				if !strings.Contains(u.Email, "qing") {
					pass = false
					break
				}
			}

		}
	}

	SaveCase("Central_User", "ListConsoleUsersByOrgOwnerWithEmailFilter", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

type ListConsoleUsersResp struct {
	Total int32          `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
	Items []*consoleUser `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
}

type consoleUser struct {
	Id           string             `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	Email        string             `protobuf:"bytes,2,opt,name=email,proto3" json:"email,omitempty"`
	FirstName    string             `protobuf:"bytes,3,opt,name=first_name,json=firstName,proto3" json:"first_name,omitempty"`
	LastName     string             `protobuf:"bytes,4,opt,name=last_name,json=lastName,proto3" json:"last_name,omitempty"`
	Status       string             `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
	OrgRole      *consoleUserRole   `protobuf:"bytes,6,opt,name=org_role,json=orgRole,proto3" json:"org_role,omitempty"`
	ProjectRoles []*consoleUserRole `protobuf:"bytes,7,rep,name=project_roles,json=projectRoles,proto3" json:"project_roles,omitempty"`
	ClusterRoles []*consoleUserRole `protobuf:"bytes,8,rep,name=cluster_roles,json=clusterRoles,proto3" json:"cluster_roles,omitempty"`
	InviteTime   string             `protobuf:"bytes,9,opt,name=invite_time,json=inviteTime,proto3" json:"invite_time,omitempty"`
	LoginTime    string             `protobuf:"bytes,10,opt,name=login_time,json=loginTime,proto3" json:"login_time,omitempty"`
}

type consoleUserRole struct {
	ScopeType string `protobuf:"bytes,1,opt,name=scope_type,json=scopeType,proto3" json:"scope_type,omitempty"`
	ScopeId   string `protobuf:"varint,2,opt,name=scope_id,json=scopeId,proto3" json:"scope_id,omitempty"`
	RbacRole  string `protobuf:"bytes,3,opt,name=rbac_role,json=rbacRole,proto3" json:"rbac_role,omitempty"`
}

func Console_OneConsole_AssignConsoleUserRole() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/assign-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	email1 := fmt.Sprintf("e2e_test_%s@pingcap.com", CurTimeStr())
	email2 := fmt.Sprintf("e2e_test_1_%s@pingcap.com", CurTimeStr())
	body := fmt.Sprintf(`{
			"emails": ["%s", "%s"],
			"org_role": {
				"rbac_role": "org:billing_admin"
			},
			"project_roles": [
				{
					"scope_id": 3199935,
					"rbac_role": "project:dev"
				},
				{
					"scope_id": 2473492,
					"rbac_role": "project:owner"
				}
			]
		}`, email1, email2)

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	assignPass := false
	if code == 200 {
		var rsp = &assignConsoleUserRoleResp{}
		err := json.Unmarshal([]byte(data), rsp)
		if err == nil {
			assignPass = true
			for _, ret := range rsp.Rets {
				if !ret.Success {
					assignPass = false
					break
				}
			}
		}
	}

	verifyPass := false
	var verifyCode int
	var verifyData string
	if assignPass {
		vUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/console-users?scope_type=ORG&email=%s", email1)
		vCode, vData, vErr := RestyExec("GET", vUrl, header, "")
		verifyCode = vCode
		verifyData = vData
		if vErr == nil && vCode == 200 {
			var rsp ListConsoleUsersResp
			if json.Unmarshal([]byte(vData), &rsp) == nil && len(rsp.Items) == 1 {
				u := rsp.Items[0]
				if u.Email == email1 &&
					u.OrgRole != nil && u.OrgRole.RbacRole == "org:billing_admin" &&
					len(u.ProjectRoles) == 2 {
					has3199935 := false
					has2473492 := false
					for _, pr := range u.ProjectRoles {
						if pr.ScopeId == "3199935" && pr.RbacRole == "project:dev" {
							has3199935 = true
						}
						if pr.ScopeId == "2473492" && pr.RbacRole == "project:owner" {
							has2473492 = true
						}
					}
					if has3199935 && has2473492 {
						verifyPass = true
					}
				}
			}
		}
	}

	SaveCase("Central_User", "AssignConsoleUserRole", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      assignPass && verifyPass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"assign_pass": assignPass,
			"verify_pass": verifyPass,
			"verify_code": verifyCode,
			"verify_data": verifyData,
		},
	})

}

type assignConsoleUserRoleResp struct {
	Rets []*assignConsoleUserRoleRet `protobuf:"bytes,1,rep,name=rets,proto3" json:"rets,omitempty"`
}

type assignConsoleUserRoleRet struct {
	Email   string `protobuf:"bytes,1,opt,name=email,proto3" json:"email,omitempty"`
	Success bool   `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"`
	Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
}

func Console_OneConsole_EditConsoleUserRole() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/edit-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	body := fmt.Sprintf(`{
			"user_id": 2482134,
			"org_role": {
				"rbac_role": "org:audit_admin"
			},
			"project_roles": [
				{
					"scope_id": 3199935,
					"rbac_role": "project:dev"
				}
			],
			"cluster_roles": [
				{
					"scope_id": %d,
					"rbac_role": "cluster:viewer"
				}
			]
		}`, clusterId)

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	editPass := code == 200

	verifyPass := false
	var verifyCode int
	var verifyData string
	if editPass {
		vUrl := DevConsoleHost + "/api/v1/orgs/1440002/console-users?scope_type=ORG&per_page=100"
		vCode, vData, vErr := RestyExec("GET", vUrl, header, "")
		verifyCode = vCode
		verifyData = vData
		if vErr == nil && vCode == 200 {
			var rsp ListConsoleUsersResp
			if json.Unmarshal([]byte(vData), &rsp) == nil {
				for _, u := range rsp.Items {
					if u.Id == "2482134" {
						if u.OrgRole != nil && u.OrgRole.RbacRole == "org:audit_admin" &&
							len(u.ProjectRoles) >= 1 {
							hasProject3199935 := false
							for _, pr := range u.ProjectRoles {
								if pr.ScopeId == "3199935" && pr.RbacRole == "project:dev" {
									hasProject3199935 = true
									break
								}
							}
							hasClusterRole := false
							for _, cr := range u.ClusterRoles {
								if cr.ScopeId == fmt.Sprintf("%d", clusterId) && cr.RbacRole == "cluster:viewer" {
									hasClusterRole = true
									break
								}
							}
							if hasProject3199935 && hasClusterRole {
								verifyPass = true
							}
						}
						break
					}
				}
			}
		}
	}

	SaveCase("Central_User", "EditConsoleUserRole", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      editPass && verifyPass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"edit_pass":   editPass,
			"verify_pass": verifyPass,
			"verify_code": verifyCode,
			"verify_data": verifyData,
		},
	})

}

func Console_OneConsole_CheckEmailAlreadyHasOrgRole() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/check-email-assigned-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	body := fmt.Sprintf(`{
			"emails": ["liqing.zhu@pingcap.com", "e2e_test_%s@pingcap.com"]
		}`, CurTimeStr())

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}
	pass := false
	if code == 200 {
		var rsp = &CheckEmailAlreadyHasOrgRoleResp{}
		err := json.Unmarshal([]byte(data), rsp)
		if err == nil && slice.Contain(rsp.HasRoleEmails, "liqing.zhu@pingcap.com") {
			pass = true
		}
	}

	SaveCase("Central_User", "EditConsoleUserRole", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})

}

type CheckEmailAlreadyHasOrgRoleResp struct {
	HasRoleEmails []string `protobuf:"bytes,1,rep,name=hasRoleEmails,proto3" json:"hasRoleEmails,omitempty"`
}

func Central_CheckUserLoginStateNotRevoked() {
	url := DevConsoleHost + "/api/v1/user/me"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "GetUserProfileV2", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code != 401,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_RevokeUserLoginStateByLogoutAllDevice() {
	url := DevConsoleHost + "/api/v1/user/revoke-login-state"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("POST", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "RevokeUserLoginStateByLogoutAllDevice", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      code == 200,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_RevokeUserLoginStateByChangePasswordCallback_TokenInvalid() {
	url := DevConsoleHost + "/revoke_login_state_callback"

	body := `{
		"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYXV0aDB8NjhiOTAyNGEwMzc1ODBmZDUxYzNjMDQzIiwiZW1haWwiOiJkZW5nc2h1aXhpb25nKzE1QHBpbmdjYXAuY29tIiwibGFzdF9wYXNzd29yZF9yZXNldCI6IjIwMjUtMTEtMThUMDY6NDA6NTguMTcwWiIsImlhdCI6MTc2MzQ0ODA1OSwiZXhwIjoxNzYzNDQ4MzU5LCJpc3MiOiJ0aWRiLWRldi1hdXRoMC1hY3Rpb24ifQ.i8WMi9LmmHgM_QmCMunygMPDAcxBelfkkhl9cHN8ugo"
	}`

	code, data, err := RestyExec("POST", url, nil, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	SaveCase("Central_User", "RevokeUserLoginStateByChangePasswordCallback", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: nil,
		ReqBody:   "",
		Pass:      code == 401,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_OneConsole_ListConsoleUsers_NoFilter() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-users?scope_type=ORG&per_page=10"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	pass := false
	if code == 200 {
		var rsp = &ListConsoleUsersResp{}
		if json.Unmarshal([]byte(data), rsp) == nil {
			pass = rsp.Total > 0 && len(rsp.Items) > 0
		}
	}

	SaveCase("Central_User", "ListConsoleUsers_NoFilter", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func Central_OneConsole_ListConsoleUsers_WithRoleFilter() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-users?scope_type=ORG&per_page=10&roles=" + url.QueryEscape("org:owner")

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	code, data, err := RestyExec("GET", url, header, "")
	if err != nil {
		code = 0
		data = err.Error()
	}

	pass := false
	if code == 200 {
		var rsp = &ListConsoleUsersResp{}
		if json.Unmarshal([]byte(data), rsp) == nil {
			pass = true
			for _, u := range rsp.Items {
				if u.OrgRole == nil || u.OrgRole.RbacRole != "org:owner" {
					pass = false
					break
				}
			}
		}
	}

	SaveCase("Central_User", "ListConsoleUsers_WithRoleFilter", CaseDetail{
		Url:       url,
		Method:    "GET",
		ReqHeader: header,
		ReqBody:   "",
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}

func Console_OneConsole_AssignConsoleUserRole_WithProjectRoles() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/assign-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	email := fmt.Sprintf("e2e_assign_full_%s@pingcap.com", CurTimeStr())
	body := fmt.Sprintf(`{
		"emails": ["%s"],
		"org_role": {
			"rbac_role": "org:member"
		},
		"project_roles": [
			{
				"scope_id": 3199935,
				"rbac_role": "project:dev"
			}
		]
	}`, email)

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	assignPass := false
	if code == 200 {
		var rsp = &assignConsoleUserRoleResp{}
		if json.Unmarshal([]byte(data), rsp) == nil && len(rsp.Rets) == 1 {
			assignPass = rsp.Rets[0].Success
		}
	}

	verifyPass := false
	var verifyCode int
	var verifyData string
	if assignPass {
		vUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/console-users?scope_type=ORG&email=%s", email)
		vCode, vData, vErr := RestyExec("GET", vUrl, header, "")
		verifyCode = vCode
		verifyData = vData
		if vErr == nil && vCode == 200 {
			var rsp ListConsoleUsersResp
			if json.Unmarshal([]byte(vData), &rsp) == nil && len(rsp.Items) == 1 {
				u := rsp.Items[0]
				if u.Email == email &&
					u.OrgRole != nil && u.OrgRole.RbacRole == "org:member" &&
					len(u.ProjectRoles) == 1 && u.ProjectRoles[0].RbacRole == "project:dev" && u.ProjectRoles[0].ScopeId == "3199935" {
					verifyPass = true
				}
			}
		}
	}

	SaveCase("Central_User", "AssignConsoleUserRole_WithProjectRoles", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      assignPass && verifyPass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"assign_pass": assignPass,
			"verify_pass": verifyPass,
			"verify_code": verifyCode,
			"verify_data": verifyData,
		},
	})
}

func Console_OneConsole_AssignConsoleUserRole_WithProjectAndClusterRoles() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/assign-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	email := fmt.Sprintf("e2e_assign_full_%s@pingcap.com", CurTimeStr())
	body := fmt.Sprintf(`{
		"emails": ["%s"],
		"org_role": {
			"rbac_role": "org:member"
		},
		"project_roles": [
			{
				"scope_id": 3199935,
				"rbac_role": "project:dev"
			}
		],
		"cluster_roles": [
			{
				"scope_id": %d,
				"rbac_role": "cluster:admin"
			}
		]
	}`, email, clusterId)

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	assignPass := false
	if code == 200 {
		var rsp = &assignConsoleUserRoleResp{}
		if json.Unmarshal([]byte(data), rsp) == nil && len(rsp.Rets) == 1 {
			assignPass = rsp.Rets[0].Success
		}
	}

	verifyPass := false
	var verifyCode int
	var verifyData string
	if assignPass {
		vUrl := DevConsoleHost + fmt.Sprintf("/api/v1/orgs/1440002/console-users?scope_type=ORG&email=%s", email)
		vCode, vData, vErr := RestyExec("GET", vUrl, header, "")
		verifyCode = vCode
		verifyData = vData
		if vErr == nil && vCode == 200 {
			var rsp ListConsoleUsersResp
			if json.Unmarshal([]byte(vData), &rsp) == nil && len(rsp.Items) == 1 {
				u := rsp.Items[0]
				if u.Email == email &&
					u.OrgRole != nil && u.OrgRole.RbacRole == "org:member" &&
					len(u.ProjectRoles) == 1 && u.ProjectRoles[0].RbacRole == "project:dev" && u.ProjectRoles[0].ScopeId == "3199935" &&
					len(u.ClusterRoles) == 1 && u.ClusterRoles[0].RbacRole == "cluster:admin" && u.ClusterRoles[0].ScopeId == fmt.Sprintf("%d", clusterId) {
					verifyPass = true
				}
			}
		}
	}

	SaveCase("Central_User", "AssignConsoleUserRole_WithProjectAndClusterRoles", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      assignPass && verifyPass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"assign_pass": assignPass,
			"verify_pass": verifyPass,
			"verify_code": verifyCode,
			"verify_data": verifyData,
		},
	})
}

func Console_OneConsole_EditConsoleUserRole_OnlyOrgRole() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/edit-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	body := `{
		"user_id": 2482134,
		"org_role": {
			"rbac_role": "org:member"
		}
	}`

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}

	editPass := code == 200

	verifyPass := false
	var verifyCode int
	var verifyData string
	if editPass {
		vUrl := DevConsoleHost + "/api/v1/orgs/1440002/console-users?scope_type=ORG&per_page=100"
		vCode, vData, vErr := RestyExec("GET", vUrl, header, "")
		verifyCode = vCode
		verifyData = vData
		if vErr == nil && vCode == 200 {
			var rsp ListConsoleUsersResp
			if json.Unmarshal([]byte(vData), &rsp) == nil {
				for _, u := range rsp.Items {
					if u.Id == "2482134" {
						if u.OrgRole != nil && u.OrgRole.RbacRole == "org:member" {
							verifyPass = true
						}
						break
					}
				}
			}
		}
	}

	SaveCase("Central_User", "EditConsoleUserRole_OnlyOrgRole", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      editPass && verifyPass,
		RspCode:   code,
		RspData:   data,
		Extra: map[string]interface{}{
			"edit_pass":   editPass,
			"verify_pass": verifyPass,
			"verify_code": verifyCode,
			"verify_data": verifyData,
		},
	})
}

func Console_OneConsole_CheckEmailAlreadyHasOrgRole_AllUnknown() {
	url := DevConsoleHost + "/api/v1/orgs/1440002/console-user/check-email-assigned-role"

	var header = map[string]string{}
	header["Content-type"] = "application/json"
	header["Authorization"] = consoleAuthorization

	body := fmt.Sprintf(`{
		"emails": ["e2e_unknown_%s@example.com", "e2e_unknown_2_%s@example.com"]
	}`, CurTimeStr(), CurTimeStr())

	code, data, err := RestyExec("POST", url, header, body)
	if err != nil {
		code = 0
		data = err.Error()
	}
	pass := false
	if code == 200 {
		var rsp = &CheckEmailAlreadyHasOrgRoleResp{}
		if json.Unmarshal([]byte(data), rsp) == nil && len(rsp.HasRoleEmails) == 0 {
			pass = true
		}
	}

	SaveCase("Central_User", "CheckEmailAlreadyHasOrgRole_AllUnknown", CaseDetail{
		Url:       url,
		Method:    "POST",
		ReqHeader: header,
		ReqBody:   body,
		Pass:      pass,
		RspCode:   code,
		RspData:   data,
	})
}
