mirror of https://github.com/casbin/casnode.git
feat: add username resetting
Signed-off-by: Kininaru <shiftregister233@outlook.com>
This commit is contained in:
parent
fa05bcbd99
commit
c216520a3a
|
@ -240,3 +240,35 @@ func (c *APIController) DeleteMember() {
|
|||
c.Data["json"] = object.DeleteMember(id)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *APIController) ResetUsername() {
|
||||
var resp Response
|
||||
memberId := c.GetSessionUser()
|
||||
newUsername := c.Input().Get("new")
|
||||
|
||||
if len(memberId) == 0 {
|
||||
resp = Response{Status: "error", Msg: "Login first"}
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
if len(newUsername) == 0 {
|
||||
resp = Response{Status: "error", Msg: "Parameter lost: new"}
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
msg := object.ResetUsername(memberId, newUsername)
|
||||
|
||||
if msg == "" {
|
||||
resp = Response{Status: "ok", Msg: "Succeed. Please login again."}
|
||||
c.SetSessionUser("")
|
||||
} else {
|
||||
resp = Response{Status: "error", Msg: msg}
|
||||
}
|
||||
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
}
|
|
@ -33,6 +33,11 @@ type Session struct {
|
|||
|
||||
func InitAdapter() {
|
||||
adapter = NewAdapter("mysql", beego.AppConfig.String("dataSourceName"))
|
||||
|
||||
_, err := adapter.engine.Query("update member set rename_quota = ? where rename_quota is null", DefaultRenameQuota)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Adapter represents the MySQL adapter for policy storage.
|
||||
|
|
|
@ -21,6 +21,7 @@ var (
|
|||
DefaultBalancePageNum = 25
|
||||
DefaultFilePageNum = 25
|
||||
DefaultMemberAdminPageNum = 100
|
||||
DefaultRenameQuota = 3
|
||||
UserNamingRestrictions = false
|
||||
HomePageNodeNum = 8
|
||||
TopicThanksCost = 15
|
||||
|
|
|
@ -56,6 +56,7 @@ type Member struct {
|
|||
OnlineStatus bool `xorm:"bool" json:"onlineStatus"`
|
||||
LastActionDate string `xorm:"varchar(40)" json:"-"`
|
||||
Status int `xorm:"int" json:"-"`
|
||||
RenameQuota int `json:"renameQuota"`
|
||||
}
|
||||
|
||||
func GetMembers() []*Member {
|
||||
|
@ -622,3 +623,50 @@ func GetMemberOnlineNum() int {
|
|||
|
||||
return int(total)
|
||||
}
|
||||
|
||||
type UpdateListItem struct {
|
||||
Table string
|
||||
Attribute string
|
||||
}
|
||||
|
||||
func ResetUsername(oldUsername string, newUsername string) string {
|
||||
if len(newUsername) == 0 || len(newUsername) > 100 || strings.Index(newUsername, " ") >= 0 {
|
||||
return "Illegal username"
|
||||
}
|
||||
if HasMember(newUsername) {
|
||||
return "User exists"
|
||||
}
|
||||
|
||||
member := GetMember(oldUsername)
|
||||
if member.RenameQuota < 1 {
|
||||
return "You have no chance to reset you name."
|
||||
}
|
||||
member.RenameQuota--
|
||||
_, err := adapter.engine.Query("update member set rename_quota = ? where id = ?", member.RenameQuota, oldUsername)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
updateList := []UpdateListItem{
|
||||
{"member", "id"},
|
||||
{"browse_record", "member_id"},
|
||||
{"consumption_record", "consumer_id"},
|
||||
{"consumption_record", "receiver_id"},
|
||||
{"favorites", "member_id"},
|
||||
{"node", "moderators"},
|
||||
{"notification", "sender_id"},
|
||||
{"notification", "receiver_id"},
|
||||
{"reply", "author"},
|
||||
{"reset_record", "member_id"},
|
||||
{"topic", "author"},
|
||||
{"upload_file_record", "member_id"},
|
||||
}
|
||||
for _, value := range updateList {
|
||||
_, err = adapter.engine.Query("update " + value.Table + " set " + value.Attribute + " = ? where " + value.Attribute + " = ?", newUsername, oldUsername)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ func initAPI() {
|
|||
beego.Router("/api/get-member-editor-type", &controllers.APIController{}, "GET:GetMemberEditorType")
|
||||
beego.Router("/api/update-member-email-reminder", &controllers.APIController{}, "POST:UpdateMemberEmailReminder")
|
||||
beego.Router("/api/get-ranking-rich", &controllers.APIController{}, "GET:GetRankingRich")
|
||||
beego.Router("/api/reset-member-username", &controllers.APIController{}, "GET:ResetUsername")
|
||||
|
||||
beego.Router("/api/get-nodes", &controllers.APIController{}, "GET:GetNodes")
|
||||
beego.Router("/api/get-node", &controllers.APIController{}, "GET:GetNode")
|
||||
|
|
|
@ -58,3 +58,13 @@ export function resetPassword(step, values) {
|
|||
body: JSON.stringify(values),
|
||||
}).then((res) => res.json());
|
||||
}
|
||||
|
||||
export function resetUsername(newUsername) {
|
||||
return fetch(
|
||||
`${Setting.ServerUrl}/api/reset-member-username?new=${newUsername}`,
|
||||
{
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
}
|
||||
).then((res) => res.json());
|
||||
}
|
||||
|
|
|
@ -482,6 +482,8 @@
|
|||
},
|
||||
"setting": {
|
||||
"Username": "Username",
|
||||
"New Username": "New Username",
|
||||
"Username has been set": "Username has been set. Please login again.",
|
||||
"Password": "Password",
|
||||
"Member already exists": "Member already exists",
|
||||
"Password empty": "Password empty",
|
||||
|
@ -502,6 +504,7 @@
|
|||
"Company": "Company",
|
||||
"Bio": "Bio",
|
||||
"Save Settings": "Save Settings",
|
||||
"Save Username": "Save Username",
|
||||
"Settings": "Settings",
|
||||
"Company title": "Company title",
|
||||
"Location": "Location",
|
||||
|
|
|
@ -486,6 +486,8 @@
|
|||
},
|
||||
"setting": {
|
||||
"Username": "用户名",
|
||||
"New Username": "新用户名",
|
||||
"Username has been set": "用户名已设置,请重新登陆",
|
||||
"Password": "密码",
|
||||
"Member already exists": "用户已存在",
|
||||
"Password empty": "密码为空",
|
||||
|
@ -506,6 +508,7 @@
|
|||
"Company": "所在公司",
|
||||
"Bio": "个人简介",
|
||||
"Save Settings": "保存设置",
|
||||
"Save Username": "保存用户名",
|
||||
"Settings": "设置",
|
||||
"Company title": "工作职位",
|
||||
"Location": "所在地",
|
||||
|
|
|
@ -201,6 +201,18 @@ class SettingsBox extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
submitNewUsername() {
|
||||
let newUsername = document.getElementById("new-username").value;
|
||||
AccountBackend.resetUsername(newUsername).then((res) => {
|
||||
if (res.status === "ok") {
|
||||
alert(i18next.t("setting:Username has been set"));
|
||||
window.location.href = "/signin";
|
||||
} else {
|
||||
alert(res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
renderSettingList(item) {
|
||||
return (
|
||||
<Link
|
||||
|
@ -521,6 +533,32 @@ class SettingsBox extends React.Component {
|
|||
{account?.id}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" align="right">
|
||||
{i18next.t("setting:New Username")}
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
className="sl"
|
||||
name="company"
|
||||
defaultValue={account?.company}
|
||||
maxLength="32"
|
||||
id="new-username"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td />
|
||||
<td width="auto" align="left">
|
||||
<input
|
||||
type="submit"
|
||||
className="super normal button"
|
||||
value={i18next.t("setting:Save Username")}
|
||||
onClick={this.submitNewUsername}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="120" align="right">
|
||||
{i18next.t("setting:Phone")}
|
||||
|
|
Loading…
Reference in New Issue