Merge branch 'develop' of https://git.mesalab.cn/dongxiaoyan/tsg_autotest into develop
This commit is contained in:
@@ -36,7 +36,7 @@ PolicyVertify
|
||||
${resultObj} Create Dictionary verifyList=${verifyList}
|
||||
|
||||
${json} json.Dumps ${resultObj} ensure_ascii=False
|
||||
${response} BasePostRequest /v1/policy/verify body=${json}
|
||||
${response} BasePostRequest /policy/verify body=${json}
|
||||
Log REQ = ${json}
|
||||
Log RES = ${response}
|
||||
Should Be True ${response['code']} == 200
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
*** Settings ***
|
||||
Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Library REST http://${host}:${port}
|
||||
Library REST http://${host}:${port}/${version}
|
||||
Library Collections
|
||||
Library RequestsLibrary
|
||||
|
||||
@@ -20,7 +20,7 @@ BasePostRequest
|
||||
BaseDeleteRequest
|
||||
[Arguments] ${requestUri} ${data}
|
||||
${headers} set variable {"Authorization":"${token}","Content-Type":"application/json"}
|
||||
create session api http://${host}:${port} ${headers}
|
||||
create session api http://${host}:${port}/${version} ${headers}
|
||||
${response}= Delete Request api ${requestUri} data=${data}
|
||||
log return data =${response}
|
||||
Should Be Equal As Strings ${response.status_code} 200
|
||||
@@ -30,7 +30,7 @@ BaseDeleteRequest
|
||||
BaseEditRequest
|
||||
[Arguments] ${requestUri} ${data}
|
||||
${headers} set variable {"Authorization":"${token}","Content-Type":"application/json"}
|
||||
create session api http://${host}:${port} ${headers}
|
||||
create session api http://${host}:${port}/${version} ${headers}
|
||||
${response}= Put Request api ${requestUri} data=${data}
|
||||
log return data =${response}
|
||||
Should Be Equal As Strings ${response.status_code} 200
|
||||
|
||||
46
02-Keyword/tsg_bfapi/LogStatistics.robot
Normal file
46
02-Keyword/tsg_bfapi/LogStatistics.robot
Normal file
@@ -0,0 +1,46 @@
|
||||
*** Settings ***
|
||||
Library RequestsLibrary
|
||||
Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Library string
|
||||
|
||||
*** Keywords ***
|
||||
GetApi
|
||||
[Arguments] ${url} ${startTime}=${None} ${endTime}=${None} ${limit}=${None} ${statisticTime}=${None} ${statisticsUnit}=${None} ${timeGranularity}=${None} ${policy_id}=${None} ${ip}=${None}
|
||||
#拼接查询条件
|
||||
${strstrartTime}= run keyword if '${startTime}'!='${None}' Set Variable startTime=${startTime}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strendTime}= run keyword if '${endTime}'!='${None}' Set Variable endTime=${endTime}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strstatisticTime}= run keyword if '${statisticTime}'!='${None}' Set Variable statisticTime=${statisticTime}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strlimit}= run keyword if '${limit}'!='${None}' Set Variable limit=${limit}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strstatisticsUnit}= run keyword if '${statisticsUnit}'!='${None}' Set Variable statisticsUnit=${statisticsUnit}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strtimeGranularity}= run keyword if '${timeGranularity}'!='${None}' Set Variable timeGranularity=${timeGranularity}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strpolicy_id} run keyword if '${policy_id}'!='${None}' Set Variable policy_id=${policy_id}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${strip} run keyword if '${ip}'!='${None}' Set Variable ip=${ip}&
|
||||
... ELSE Set Variable ${EMPTY}
|
||||
${condition} catenate SEPARATOR= ${strstrartTime} ${strendTime} ${strstatisticTime} ${strlimit} ${strstatisticsUnit} ${strtimeGranularity} ${strpolicy_id} ${ip}
|
||||
#创建请求信息
|
||||
${header} Create Dictionary Content-Type=application/x-www-form-urlencoded Authorization=${token}
|
||||
Create Session api http://${host}:${port}/${version}
|
||||
#发送请求
|
||||
${remoteResponse} Get Request api ${url}?${condition} headers=${header}
|
||||
log ${remoteResponse}
|
||||
${response} to json ${remoteResponse.content}
|
||||
#验证请求是否成功
|
||||
Should Be Equal As Strings ${remoteResponse.status_code} 200
|
||||
Should Be Equal As Strings ${response}[code] 200
|
||||
#请求大数据
|
||||
#sql拼接
|
||||
#BigData ${sql}
|
||||
|
||||
BigData
|
||||
[Arguments] ${sql}
|
||||
#创建请求信息
|
||||
Create Session api http://192.168.40.224:9999
|
||||
#发送请求
|
||||
${remoteResponse} Get Request api ?query= ${sql}
|
||||
@@ -29,4 +29,32 @@ GetLogList
|
||||
Should Contain ${logs}"" ${client_ip}
|
||||
Should Contain ${logs}"" ${policy_id}
|
||||
Should Contain ${logs}"" ${parmkey}
|
||||
Should Contain ${logs}"${parmkey}" ${parmvalue}
|
||||
Should Contain ${logs}"${parmkey}" ${parmvalue}
|
||||
|
||||
|
||||
|
||||
GetLogListSize
|
||||
[Documentation]
|
||||
... 描述:ProxyPinning
|
||||
...
|
||||
[Arguments] ${logType} ${startTime} ${endTime} ${client_ip} ${policy_id} ${parmkey} ${parmvalue}
|
||||
${logCondition} GetALLLogCondition ${logType} ${startTime} ${endTime} ${client_ip} ${policy_id} 10000 1
|
||||
log ${logCondition}
|
||||
${LogListResponse} PostRemoteData /log/list ${logCondition}
|
||||
Should Be Equal As Strings ${LogListResponse.status_code} 200
|
||||
${returnData} To Json ${LogListResponse.content}
|
||||
${data} Get From Dictionary ${returnData} data
|
||||
${len} Get Length ${data}[list]
|
||||
[Return] ${len}
|
||||
|
||||
|
||||
GetLogCount
|
||||
[Arguments] ${logType} ${startTime} ${endTime} ${client_ip} ${policy_id} ${parmkey} ${parmvalue}
|
||||
${logCondition} GetALLLogCondition ${logType} ${startTime} ${endTime} ${client_ip} ${policy_id} 10000 1
|
||||
${LogListResponse} PostRemoteData /log/count ${logCondition}
|
||||
Should Be Equal As Strings ${LogListResponse.status_code} 200
|
||||
${returnData} To Json ${LogListResponse.content}
|
||||
${len} Set Variable ${LogListResponse.json()}[data][total]
|
||||
#${len} Get From Dictionary ${returnData} total
|
||||
[Return] ${len}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
*** Settings ***
|
||||
Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Library REST http://${host}:${port}
|
||||
Library REST http://${host}:${port}/${version}
|
||||
Library Collections
|
||||
Library SSHLibrary
|
||||
Resource PolicyObject.robot
|
||||
@@ -13,7 +13,7 @@ Login
|
||||
[Tags] tsg_adc tsg_bf_api
|
||||
#[Arguments] ${username} ${password} ${authmode} ${authCode} ${ldapId}
|
||||
# 毕方接口用户名密码
|
||||
GET /v1/user/encryptpwd?password=${password}
|
||||
GET /user/encryptpwd?password=${password}
|
||||
Object response body
|
||||
#OUTPUT response body
|
||||
#${rescode} Integer $.code
|
||||
@@ -33,7 +33,7 @@ Login
|
||||
#getToken##################################################################################
|
||||
#log ${username}
|
||||
#log ${pwdstr}
|
||||
POST /v1/user/login?username=${username}&password=${encodePassword}&authMode=${authmode}
|
||||
POST /user/login?username=${username}&password=${encodePassword}&authMode=${authmode}
|
||||
Object response body
|
||||
#OUTPUT response body
|
||||
Integer $.code 200
|
||||
@@ -51,7 +51,7 @@ Login
|
||||
|
||||
Logout
|
||||
[Tags] tsg_adc tsg_bf_api
|
||||
POST /v1/user/logout headers=${headers}
|
||||
POST /user/logout headers=${headers}
|
||||
Object response body
|
||||
Integer $.code 200
|
||||
${rescode} Integer $.code
|
||||
|
||||
@@ -3,7 +3,7 @@ Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Resource ../tsg_common/ManagePolicyBody.robot
|
||||
Resource ../tsg_common/ManageObjectBody.robot
|
||||
Resource ../../02-Keyword/tsg_bfapi/policy_file_interface/FunctionalKeywords.robot
|
||||
Library REST http://${host}:${port}
|
||||
Library REST http://${host}:${port}/${version}
|
||||
Library Collections
|
||||
Library RequestsLibrary
|
||||
Resource Common.robot
|
||||
@@ -52,17 +52,17 @@ AddLocalIPObject
|
||||
|
||||
DelLocalIPObject
|
||||
log to_DelLocalIPObject
|
||||
${response} BaseDeleteRequest /v1/policy/object {"objectIds":[${testClentID}]}
|
||||
${response} BaseDeleteRequest /policy/object {"objectIds":[${testClentID}]}
|
||||
#${response_code} Get From Dictionary ${response} code
|
||||
#Should Be Equal As Strings ${response} {'code': 200, 'msg': 'Success', 'success': True}
|
||||
SET GLOBAL VARIABLE ${testClentID} ${EMPTY}
|
||||
${response} BaseDeleteRequest /v1/policy/object {"objectIds":[${testClentSubID}]}
|
||||
${response} BaseDeleteRequest /policy/object {"objectIds":[${testClentSubID}]}
|
||||
SET GLOBAL VARIABLE ${testClentSubID} ${EMPTY}
|
||||
|
||||
AddObject
|
||||
[Arguments] ${body}
|
||||
#addIPobject#################################################################################
|
||||
${response} BasePostRequest /v1/policy/object body=${body}
|
||||
${response} BasePostRequest /policy/object body=${body}
|
||||
#log ${response}
|
||||
${objectId} Set Variable ${response['data']['objectList'][0]['objectId']}
|
||||
${rescodeReturn} Set Variable ${response['code']}
|
||||
@@ -72,7 +72,7 @@ AddObject2
|
||||
[Arguments] ${returnData} ${policyList}
|
||||
${body} ObjectParamsOpertion ${returnData} ${policyList}
|
||||
|
||||
${response} BasePostRequest /v1/policy/object body=${body}
|
||||
${response} BasePostRequest /policy/object body=${body}
|
||||
${objectId} Set Variable ${response['data']['objectList'][0]['objectId']}
|
||||
${rescodeReturn} Set Variable ${response['code']}
|
||||
[Return] ${rescodeReturn} ${objectId}
|
||||
@@ -84,7 +84,7 @@ EditObject
|
||||
DeleteObjectbak
|
||||
[Arguments] ${objectids}
|
||||
${body} String {"objectIds":[${objectids}]}
|
||||
DELETE /v1/policy/object body=${body} headers=${headers}
|
||||
DELETE /policy/object body=${body} headers=${headers}
|
||||
Object response body
|
||||
log DeleteObject
|
||||
log dxytestOUtputstart
|
||||
@@ -96,7 +96,7 @@ DeleteObjectbak
|
||||
|
||||
AddPolicy
|
||||
[Arguments] ${body}
|
||||
${response} BasePostRequest /v1/policy/compile body=${body}
|
||||
${response} BasePostRequest /policy/compile body=${body}
|
||||
#log ${response}
|
||||
${policyId} Set Variable ${response['data']['policyList'][0]['policyId']}
|
||||
${rescode} Set Variable ${response['code']}
|
||||
@@ -104,22 +104,23 @@ AddPolicy
|
||||
|
||||
AddPolicy2
|
||||
[Arguments] ${returnData} ${policyList}
|
||||
${body} PolicyParamsOpertion ${returnData} ${policyList}
|
||||
${body} PolicyParamsOpertion ${returnData} ${policyList} add
|
||||
|
||||
${response} BasePostRequest /v1/policy/compile body=${body}
|
||||
${response} BasePostRequest /policy/compile body=${body}
|
||||
${policyId} Set Variable ${response['data']['policyList'][0]['policyId']}
|
||||
${rescode} Set Variable ${response['code']}
|
||||
[Return] ${rescode} ${policyId}
|
||||
|
||||
EditPolicy
|
||||
[Arguments] ${body}
|
||||
${response} BaseEditRequest /v1/policy/compile ${body}
|
||||
[Arguments] ${policyList} ${opAction}
|
||||
${body} PolicyParamsOpertion ${1} ${policyList} ${opAction}
|
||||
${response} BaseEditRequest /policy/compile ${body}
|
||||
[Return] ${rescode}
|
||||
|
||||
DeletePolicybak
|
||||
[Arguments] ${policyids}
|
||||
${body} String {"policyType":"tsg_security","policyIds":[${policyids}]}
|
||||
DELETE /v1/policy/compile body=${body} headers=${headers}
|
||||
DELETE /policy/compile body=${body} headers=${headers}
|
||||
Object response body
|
||||
log DeletePolicy
|
||||
Output response body
|
||||
@@ -131,7 +132,7 @@ DeletePolicy
|
||||
[Arguments] ${body}
|
||||
#删除策略
|
||||
log toDeletePolicy_DeletePolicyDeletePolicy
|
||||
${response} BaseDeleteRequest /v1/policy/compile ${body}
|
||||
${response} BaseDeleteRequest /policy/compile ${body}
|
||||
#{"policyType":"tsg_security","policyIds":[${policyids}]}
|
||||
${response_code} Get From Dictionary ${response} code
|
||||
Should Be Equal As Strings ${response_code} 200
|
||||
@@ -143,7 +144,7 @@ DeleteObject
|
||||
[Arguments] ${objectids}
|
||||
#删除对象
|
||||
log todeleteobj
|
||||
${response} BaseDeleteRequest /v1/policy/object {"objectIds":[${objectids}]}
|
||||
${response} BaseDeleteRequest /policy/object {"objectIds":[${objectids}]}
|
||||
${response_code} Get From Dictionary ${response} code
|
||||
#log aaaaaaaaaa:${response_code}
|
||||
Should Be Equal As Strings ${response_code} 200
|
||||
@@ -166,7 +167,8 @@ DeletePolicyAndObject
|
||||
END
|
||||
#删除对象
|
||||
log todeleteobj_DeletePolicyAndObject
|
||||
DeleteObject ${objectids}
|
||||
Run Keyword If "${objectids}"=="${EMPTY}" log no obj to del
|
||||
... ELSE DeleteObject ${objectids}
|
||||
|
||||
DeleteAfterCase
|
||||
[Arguments] ${policyids} ${objectids}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
*** Settings ***
|
||||
Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Library REST http://${host}:${port}
|
||||
Library REST http://${host}:${port}/${version}
|
||||
Library Collections
|
||||
Library RequestsLibrary
|
||||
Resource Common.robot
|
||||
@@ -9,7 +9,7 @@ Resource Common.robot
|
||||
ApiAddTags
|
||||
[Arguments] ${body}
|
||||
#ApiAddTags#################################################################################
|
||||
${response} BasePostRequest /v1/customize/tags body=${body}
|
||||
${response} BasePostRequest /customize/tags body=${body}
|
||||
#log ${response}
|
||||
${tagId} Set Variable ${response['data']['tagList'][0]['id']}
|
||||
${rescodeReturn} Set Variable ${response['code']}
|
||||
@@ -23,7 +23,7 @@ ApiDeleteTags
|
||||
[Arguments] ${body}
|
||||
#删除策略
|
||||
log toApiDeleteTags
|
||||
${response} BaseDeleteRequest /v1/customize/tags ${body}
|
||||
${response} BaseDeleteRequest /customize/tags ${body}
|
||||
${response_code} Get From Dictionary ${response} code
|
||||
Should Be Equal As Strings ${response_code} 200
|
||||
${response} Convert to String ${response}
|
||||
|
||||
@@ -103,6 +103,29 @@ CreatePolicyFile3
|
||||
Log profileId:${profileId}
|
||||
[Return] ${response}
|
||||
|
||||
CreatePolicyFileNoFile
|
||||
[Documentation]
|
||||
... 必传参数:url
|
||||
... 可选参数:data(不传时使用默认值)
|
||||
[Arguments] ${url} ${data}
|
||||
${suffix} Generate Random String
|
||||
${profileName} Catenate SEPARATOR=_ test ${suffix}
|
||||
${listlenth}= Get Length ${data}
|
||||
${requestbody} Set Variable {"opAction":"add","returnData":1,"trafficMirrorList":[{"profileName":"${profileName}","addrType":"mac","isValid":1,"addrArray":["00:A1:B2:06:C3:29"]}]}
|
||||
FOR ${var} IN RANGE ${listlenth}
|
||||
#log ${var}
|
||||
${request} Set Variable ${data}[${var}]
|
||||
END
|
||||
${content} Post-Request ${url} ${requestbody}
|
||||
${msg} Set Variable ${content['msg']}
|
||||
${list} Set Variable ${content['data']['list']}
|
||||
${profileId} Set Variable ${list[0]['profileId']}
|
||||
${profileName} Set Variable ${list[0]['profileName']}
|
||||
${response} Create Dictionary msg=${msg} profileId=${profileId} profileName=${profileName}
|
||||
Log add operation:${msg}
|
||||
Log profileId:${profileId}
|
||||
[Return] ${response}
|
||||
|
||||
CreatePolicyMutipartFile
|
||||
[Documentation]
|
||||
... 必传参数:url、filePath(文件路径)、pubFileName(证书文件名)、priFileName(私钥文件名)
|
||||
|
||||
@@ -18,7 +18,8 @@ ${Tsg_Passwd} tsg_passwd
|
||||
# tsg_help指令返回值对比文件路径
|
||||
${Tsg_Help_file_Path} cli_files/tsg_help.txt
|
||||
# tsg_show指令查询时附加sql条件
|
||||
${Tsg_Show_Added_Sql} "order by time desc limit 20 " --querey
|
||||
${Tsg_Show_Added_Sql} "order by time desc limit 1"
|
||||
${Tsg_Show_Added_Sql_Query} --query
|
||||
# tsg_show指令返回数据flowType和sled参数值
|
||||
${Tsg_Show_FlowType_Values} inline|intercomm|mirror
|
||||
${Tsg_Show_Sled_Values} mcn0|mcn1|mcn2|mcn3
|
||||
@@ -273,7 +274,7 @@ Tsg_Show_Interface
|
||||
... 描述:执行'tsg_show --interface'指令,并验证返回值
|
||||
... 参数:无
|
||||
... 返回:无
|
||||
${str} Set Variable ${Tsg_Show} --interface -- ${Tsg_Show_Added_Sql}
|
||||
${str} Set Variable ${Tsg_Show} --interface -- ${Tsg_Show_Added_Sql} ${Tsg_Show_Added_Sql_Query}
|
||||
${stime} Get Time
|
||||
@{list} Run5 ${str}
|
||||
${etime} Get Time
|
||||
@@ -288,7 +289,7 @@ Tsg_Show_APP
|
||||
... 描述:执行'tsg_show --app'指令,并验证返回值
|
||||
... 参数:无
|
||||
... 返回:无
|
||||
${str} Set Variable ${Tsg_Show} --app -- ${Tsg_Show_Added_Sql}
|
||||
${str} Set Variable ${Tsg_Show} --app -- ${Tsg_Show_Added_Sql} ${Tsg_Show_Added_Sql_Query}
|
||||
${stime} Get Time
|
||||
@{list} Run5 ${str}
|
||||
${etime} Get Time
|
||||
@@ -303,7 +304,7 @@ Tsg_Show_Protocol
|
||||
... 描述:执行'tsg_show --protocol'指令,并验证返回值
|
||||
... 参数:无
|
||||
... 返回:无
|
||||
${str} Set Variable ${Tsg_Show} --protocol -- ${Tsg_Show_Added_Sql}
|
||||
${str} Set Variable ${Tsg_Show} --protocol -- ${Tsg_Show_Added_Sql} ${Tsg_Show_Added_Sql_Query}
|
||||
${stime} Get Time
|
||||
@{list} Run5 ${str}
|
||||
${etime} Get Time
|
||||
@@ -318,7 +319,7 @@ Tsg_Show_Stream
|
||||
... 描述:执行'tsg_show --stream'指令,并验证返回值
|
||||
... 参数:无
|
||||
... 返回:无
|
||||
${str} Set Variable ${Tsg_Show} --stream -- ${Tsg_Show_Added_Sql}
|
||||
${str} Set Variable ${Tsg_Show} --stream -- ${Tsg_Show_Added_Sql} ${Tsg_Show_Added_Sql_Query}
|
||||
${stime} Get Time
|
||||
@{list} Run5 ${str}
|
||||
${etime} Get Time
|
||||
@@ -333,7 +334,7 @@ Tsg_Show_Intercept
|
||||
... 描述:执行'tsg_show --intercept'指令,并验证返回值
|
||||
... 参数:无
|
||||
... 返回:无
|
||||
${str} Set Variable ${Tsg_Show} --intercept -- ${Tsg_Show_Added_Sql}
|
||||
${str} Set Variable ${Tsg_Show} --intercept -- ${Tsg_Show_Added_Sql} ${Tsg_Show_Added_Sql_Query}
|
||||
${stime} Get Time
|
||||
@{list} Run5 ${str}
|
||||
${etime} Get Time
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
*** Settings ***
|
||||
Resource ../../03-Variable/BifangApiVariable.txt
|
||||
Library REST http://${host}:${port}
|
||||
Library REST http://${host}:${port}/${version}
|
||||
Library Collections
|
||||
Library ExtensionLibrary
|
||||
Resource ../tsg_bfapi/LoginLogout.robot
|
||||
|
||||
@@ -33,7 +33,7 @@ PolicyParamsOpertion
|
||||
... policyList: 必传,字典类型。字典内可选参数信息:
|
||||
... 其它参数默认值见../../03-Variable/PolicyObjectDefault.txt
|
||||
|
||||
[Arguments] ${returnData} ${policyList}
|
||||
[Arguments] ${returnData} ${policyList} ${opAction}
|
||||
${emptyList} Create List
|
||||
# 断言必传参数
|
||||
# Should Not Be Empty ${policyList}[policyType]
|
||||
@@ -72,13 +72,17 @@ PolicyParamsOpertion
|
||||
Set To Dictionary ${policyList} userRegion=${Default_UserRegion}
|
||||
${userRegion} Run Keyword If "${return}"=="FAIL" or '${userRegion}'=="${EMPTY}" Set Variable ""
|
||||
... ELSE Set Variable ${userRegion}
|
||||
|
||||
#针对主动防御特殊处理,主动防御不应用对象
|
||||
${active_defence_emptyList} Create List
|
||||
${return} ${policyType} Run Keyword And Ignore Error Set Variable ${policyList}[policyType]
|
||||
Run Keyword If "${policyType}"=="active_defence" Set To Dictionary ${policyList} referenceObject=${active_defence_emptyList}
|
||||
Run Keyword If "${policyType}"=="active_defence" Set To Dictionary ${policyList} appObjectIdArray=${active_defence_emptyList}
|
||||
# 转为json结构并返回
|
||||
${dict} Create Dictionary opAction=add returnData=${returnData} policyList=${policyList}
|
||||
${dict} Create Dictionary opAction=${opAction} returnData=${returnData} policyList=${policyList}
|
||||
${json} json.Dumps ${dict} ensure_ascii=False
|
||||
${json} Replace String ${json} "method:rst" ${userRegion}
|
||||
#${json} Evaluate ${userRegion}.replace('"method"','${userRegion}')
|
||||
#${json} Replace String ${json} "' {
|
||||
#${json} Replace String ${json} \" "
|
||||
|
||||
Log Policy_Request_Body-${json}
|
||||
[Return] ${json}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user