Use Casdoor authentication.

This commit is contained in:
Yang Luo 2021-06-01 20:51:13 +08:00
parent 8ce23ac473
commit 9f260a7a01
60 changed files with 1009 additions and 3334 deletions

46
auth/jwt.go Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
import "github.com/dgrijalva/jwt-go"
type Claims struct {
Organization string `json:"organization"`
Username string `json:"username"`
Type string `json:"type"`
Name string `json:"name"`
Avatar string `json:"avatar"`
Email string `json:"email"`
Phone string `json:"phone"`
Affiliation string `json:"affiliation"`
Tag string `json:"tag"`
IsAdmin bool `json:"isAdmin"`
AccessToken string `json:"accessToken"`
jwt.StandardClaims
}
func ParseJwtToken(token string) (*Claims, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &Claims{}, func(token *jwt.Token) (interface{}, error) {
return []byte(authConfig.JwtSecret), nil
})
if tokenClaims != nil {
if claims, ok := tokenClaims.Claims.(*Claims); ok && tokenClaims.Valid {
return claims, nil
}
}
return nil, err
}

39
auth/token.go Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
import (
"context"
"fmt"
"golang.org/x/oauth2"
)
func GetOAuthToken(code string, state string) (*oauth2.Token, error) {
config := oauth2.Config{
ClientID: authConfig.ClientId,
ClientSecret: authConfig.ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: fmt.Sprintf("%s/api/login/oauth/authorize", authConfig.Endpoint),
TokenURL: fmt.Sprintf("%s/api/login/oauth/access_token", authConfig.Endpoint),
AuthStyle: oauth2.AuthStyleInParams,
},
//RedirectURL: redirectUri,
Scopes: nil,
}
token, err := config.Exchange(context.Background(), code)
return token, err
}

92
auth/user.go Normal file
View File

@ -0,0 +1,92 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package auth
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type AuthConfig struct {
Endpoint string
ClientId string
ClientSecret string
JwtSecret string
}
var authConfig AuthConfig
type User struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
UpdatedTime string `xorm:"varchar(100)" json:"updatedTime"`
Id string `xorm:"varchar(100)" json:"id"`
Type string `xorm:"varchar(100)" json:"type"`
Password string `xorm:"varchar(100)" json:"password"`
DisplayName string `xorm:"varchar(100)" json:"displayName"`
Avatar string `xorm:"varchar(255)" json:"avatar"`
Email string `xorm:"varchar(100)" json:"email"`
Phone string `xorm:"varchar(100)" json:"phone"`
Affiliation string `xorm:"varchar(100)" json:"affiliation"`
Tag string `xorm:"varchar(100)" json:"tag"`
Language string `xorm:"varchar(100)" json:"language"`
Score int `json:"score"`
IsAdmin bool `json:"isAdmin"`
IsGlobalAdmin bool `json:"isGlobalAdmin"`
IsForbidden bool `json:"isForbidden"`
Hash string `xorm:"varchar(100)" json:"hash"`
PreHash string `xorm:"varchar(100)" json:"preHash"`
Github string `xorm:"varchar(100)" json:"github"`
Google string `xorm:"varchar(100)" json:"google"`
QQ string `xorm:"qq varchar(100)" json:"qq"`
WeChat string `xorm:"wechat varchar(100)" json:"wechat"`
Properties map[string]string `json:"properties"`
}
func InitConfig(endpoint string, clientId string, clientSecret string, jwtSecret string) {
authConfig = AuthConfig{
Endpoint: endpoint,
ClientId: clientId,
ClientSecret: clientSecret,
JwtSecret: jwtSecret,
}
}
func GetUsers(owner string) []*User {
url := fmt.Sprintf("%s/api/get-users?owner=%s", authConfig.Endpoint, owner)
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
var users []*User
err = json.Unmarshal(bytes, &users)
if err != nil {
panic(err)
}
return users
}

View File

@ -3,6 +3,7 @@ httpport = 7000
runmode = dev
SessionOn = true
copyrequestbody = true
driverName = mysql
dataSourceName = root:123@tcp(localhost:3306)/
dbName = casnode
AuthState = "casnode"
@ -28,4 +29,8 @@ mailUser = ""
mailPass = ""
mailHost = ""
mailPort = ""
httpProxy = "127.0.0.1:10808"
httpProxy = "127.0.0.1:10808"
casdoorEndpoint = http://localhost:8000
clientId = 014ae4bd048734ca2dea
clientSecret = xxx
jwtSecret = CasdoorSecret

File diff suppressed because it is too large Load Diff

68
controllers/auth.go Normal file
View File

@ -0,0 +1,68 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package controllers
import (
"github.com/astaxie/beego"
"github.com/casbin/casnode/auth"
)
var CasdoorEndpoint = beego.AppConfig.String("casdoorEndpoint")
var ClientId = beego.AppConfig.String("clientId")
var ClientSecret = beego.AppConfig.String("clientSecret")
var JwtSecret = beego.AppConfig.String("jwtSecret")
func init() {
auth.InitConfig(CasdoorEndpoint, ClientId, ClientSecret, JwtSecret)
}
func (c *ApiController) Login() {
code := c.Input().Get("code")
state := c.Input().Get("state")
token, err := auth.GetOAuthToken(code, state)
if err != nil {
panic(err)
}
claims, err := auth.ParseJwtToken(token.AccessToken)
if err != nil {
panic(err)
}
claims.AccessToken = token.AccessToken
c.SetSessionUser(claims)
resp := &Response{Status: "ok", Msg: "", Data: claims}
c.Data["json"] = resp
c.ServeJSON()
}
func (c *ApiController) Logout() {
var resp Response
c.SetSessionUser(nil)
resp = Response{Status: "ok", Msg: ""}
c.Data["json"] = resp
c.ServeJSON()
}
func (c *ApiController) GetUsers() {
owner := c.Input().Get("owner")
c.Data["json"] = auth.GetUsers(owner)
c.ServeJSON()
}

View File

@ -23,7 +23,7 @@ import (
)
func (c *ApiController) AddThanks() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
idStr := c.Input().Get("id")
thanksType := c.Input().Get("thanksType") //1 means topic, 2 means reply
@ -92,7 +92,7 @@ func (c *ApiController) AddThanks() {
}
func (c *ApiController) GetConsumptionRecord() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
limitStr := c.Input().Get("limit")
pageStr := c.Input().Get("page")
defaultLimit := object.DefaultBalancePageNum
@ -118,7 +118,7 @@ func (c *ApiController) GetConsumptionRecord() {
}
func (c *ApiController) GetCheckinBonus() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
checkinDate := object.GetMemberCheckinDate(memberId)
date := util.GetDateStr()
@ -152,7 +152,7 @@ func (c *ApiController) GetCheckinBonus() {
}
func (c *ApiController) GetCheckinBonusStatus() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
checkinDate := object.GetMemberCheckinDate(memberId)
date := util.GetDateStr()

View File

@ -16,6 +16,8 @@ package controllers
import (
"github.com/astaxie/beego"
"github.com/casbin/casnode/auth"
"github.com/casbin/casnode/util"
"github.com/casbin/casnode/object"
)
@ -24,21 +26,41 @@ type ApiController struct {
beego.Controller
}
func (c *ApiController) GetSessionUser() string {
user := c.GetSession("username")
if user == nil {
return ""
func (c *ApiController) GetSessionUser() *auth.Claims {
s := c.GetSession("user")
if s == nil {
return nil
}
return user.(string)
claims := &auth.Claims{}
err := util.JsonToStruct(s.(string), claims)
if err != nil {
panic(err)
}
return claims
}
func (c *ApiController) SetSessionUser(user string) {
c.SetSession("username", user)
func (c *ApiController) SetSessionUser(claims *auth.Claims) {
if claims == nil {
c.DelSession("user")
return
}
s := util.StructToJson(claims)
c.SetSession("user", s)
}
func (c *ApiController) GetSessionUsername() string {
claims := c.GetSessionUser()
if claims == nil {
return ""
}
return claims.Username
}
func (c *ApiController) RequireLogin() bool {
if c.GetSessionUser() == "" {
if c.GetSessionUser() == nil {
c.Data["json"] = Response{Status: "error", Msg: "errorNeedSignin", Data: ""}
c.ServeJSON()

View File

@ -26,7 +26,7 @@ func (c *ApiController) AddFavorites() {
favoritesTypeStr := c.Input().Get("type")
favoritesType := util.ParseInt(favoritesTypeStr)
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
favorites := object.Favorites{
//Id: util.IntToString(object.GetFavoritesCount()) + memberId,
FavoritesType: favoritesType,
@ -56,7 +56,7 @@ func (c *ApiController) AddFavorites() {
NotificationType: 4,
ObjectId: topicId,
CreatedTime: util.GetCurrentTime(),
SenderId: c.GetSessionUser(),
SenderId: c.GetSessionUsername(),
ReceiverId: object.GetTopicAuthor(topicId),
Status: 1,
}
@ -80,7 +80,7 @@ func (c *ApiController) AddFavorites() {
}
func (c *ApiController) DeleteFavorites() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
objectId := c.Input().Get("id")
favoritesTypeStr := c.Input().Get("type")
favoritesType := util.ParseInt(favoritesTypeStr)
@ -115,7 +115,7 @@ func (c *ApiController) DeleteFavorites() {
}
func (c *ApiController) GetFavoritesStatus() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
objectId := c.Input().Get("id")
favoritesTypeStr := c.Input().Get("type")
favoritesType := util.ParseInt(favoritesTypeStr)
@ -133,7 +133,7 @@ func (c *ApiController) GetFavoritesStatus() {
}
func (c *ApiController) GetFavorites() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
favoritesTypeStr := c.Input().Get("type")
limitStr := c.Input().Get("limit")
pageStr := c.Input().Get("page")
@ -177,7 +177,7 @@ func (c *ApiController) GetFavorites() {
}
func (c *ApiController) GetAccountFavoriteNum() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var res [4]int
var wg sync.WaitGroup

View File

@ -39,7 +39,7 @@ func (c *ApiController) GetFiles() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
limitStr := c.Input().Get("limit")
pageStr := c.Input().Get("page")
defaultLimit := object.DefaultFilePageNum
@ -64,7 +64,7 @@ func (c *ApiController) GetFiles() {
}
func (c *ApiController) GetFileNum() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
num := fileNumResp{Num: object.GetFilesNum(memberId), MaxNum: object.GetMemberFileQuota(memberId)}
resp := Response{Status: "ok", Msg: "success", Data: num}
@ -85,7 +85,7 @@ func (c *ApiController) AddFileRecord() {
}
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
uploadFileNum := object.GetFilesNum(memberId)
if uploadFileNum >= object.GetMemberFileQuota(memberId) {
@ -121,7 +121,7 @@ func (c *ApiController) AddFileRecord() {
func (c *ApiController) DeleteFile() {
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
fileInfo := object.GetFile(id)
@ -165,7 +165,7 @@ func (c *ApiController) GetFile() {
func (c *ApiController) UpdateFileDescribe() {
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
var desc fileDescribe
@ -194,7 +194,7 @@ func (c *ApiController) UploadFile() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
fileBase64 := c.Ctx.Request.Form.Get("file")
fileType := c.Ctx.Request.Form.Get("type")
fileName := c.Ctx.Request.Form.Get("name")
@ -211,7 +211,7 @@ func (c *ApiController) ModeratorUpload() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
if !object.GetMember(memberId).IsModerator {
c.Data["json"] = Response{Status: "error", Msg: "You have no permission to upload files here. Need to be moderator."}
c.ServeJSON()
@ -233,7 +233,7 @@ func (c *ApiController) UploadAvatar() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
avatarBase64 := c.Ctx.Request.Form.Get("avatar")
index := strings.Index(avatarBase64, ",")
if index < 0 || (avatarBase64[0:index] != "data:image/png;base64" && avatarBase64[0:index] != "data:image/jpeg;base64") {

View File

@ -73,7 +73,7 @@ func (c *ApiController) GetMemberAvatar() {
}
func (c *ApiController) UpdateMemberAvatar() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
avatar := c.Input().Get("avatar")
c.Data["json"] = object.UpdateMemberAvatar(memberId, avatar)
@ -81,7 +81,7 @@ func (c *ApiController) UpdateMemberAvatar() {
}
func (c *ApiController) UpdateMemberEmailReminder() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
status := c.Input().Get("status")
c.Data["json"] = Response{Status: "ok", Msg: "success", Data: object.ChangeMemberEmailReminder(memberId, status)}
@ -95,7 +95,7 @@ func (c *ApiController) UpdateMember() {
var memberInfo object.AdminMemberInfo
var resp Response
if !object.CheckModIdentity(c.GetSessionUser()) {
if !object.CheckModIdentity(c.GetSessionUsername()) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
c.Data["json"] = resp
c.ServeJSON()
@ -116,7 +116,7 @@ func (c *ApiController) UpdateMember() {
func (c *ApiController) UpdateMemberInfo() {
id := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var tempMember object.Member
err := json.Unmarshal(c.Ctx.Input.RequestBody, &tempMember)
@ -145,7 +145,7 @@ func (c *ApiController) UpdateMemberInfo() {
}
func (c *ApiController) GetMemberEditorType() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var resp Response
var editorType string
@ -169,7 +169,7 @@ func (c *ApiController) GetRankingRich() {
func (c *ApiController) UpdateMemberEditorType() {
editorType := c.Input().Get("editorType")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var resp Response
@ -188,7 +188,7 @@ func (c *ApiController) UpdateMemberEditorType() {
func (c *ApiController) UpdateMemberLanguage() {
language := c.Input().Get("language")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var resp Response
@ -206,7 +206,7 @@ func (c *ApiController) UpdateMemberLanguage() {
}
func (c *ApiController) GetMemberLanguage() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var resp Response
var language string
@ -226,7 +226,7 @@ func (c *ApiController) GetMemberLanguage() {
func (c *ApiController) AddMember() {
var member object.Member
var resp Response
if !object.CheckModIdentity(c.GetSessionUser()) {
if !object.CheckModIdentity(c.GetSessionUsername()) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
c.Data["json"] = resp
c.ServeJSON()
@ -259,7 +259,7 @@ func (c *ApiController) DeleteMember() {
func (c *ApiController) ResetUsername() {
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
newUsername := c.Input().Get("new")
if len(memberId) == 0 {
@ -280,7 +280,7 @@ func (c *ApiController) ResetUsername() {
if msg == "" {
resp = Response{Status: "ok", Msg: "Succeed. Please login again."}
c.SetSessionUser("")
c.SetSessionUser(nil)
} else {
resp = Response{Status: "error", Msg: msg}
}

View File

@ -55,8 +55,8 @@ func (c *ApiController) UpdateNode() {
var resp Response
var node object.Node
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}
@ -75,8 +75,8 @@ func (c *ApiController) AddNode() {
var node object.Node
var resp Response
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}
@ -110,8 +110,8 @@ func (c *ApiController) AddNode() {
func (c *ApiController) DeleteNode() {
id := c.Input().Get("id")
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}
@ -206,7 +206,7 @@ func (c *ApiController) AddNodeBrowseCount() {
var resp Response
hitRecord := object.BrowseRecord{
MemberId: c.GetSessionUser(),
MemberId: c.GetSessionUsername(),
RecordType: 1,
ObjectId: nodeId,
CreatedTime: util.GetCurrentTime(),
@ -227,7 +227,7 @@ func (c *ApiController) AddNodeModerators() {
var moderators addNodeModerator
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
if !object.CheckModIdentity(memberId) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
c.Data["json"] = resp
@ -263,7 +263,7 @@ func (c *ApiController) DeleteNodeModerators() {
var moderators deleteNodeModerator
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
if !object.CheckModIdentity(memberId) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
c.Data["json"] = resp

View File

@ -28,7 +28,7 @@ func (c *ApiController) AddNotification() {
panic(err)
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
notification := object.Notification{
//Id: util.IntToString(object.GetNotificationId()),
NotificationType: tempNotification.NotificationType,
@ -56,7 +56,7 @@ func (c *ApiController) AddNotification() {
}
func (c *ApiController) GetNotifications() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
limitStr := c.Input().Get("limit")
pageStr := c.Input().Get("page")
defaultLimit := object.DefaultNotificationPageNum
@ -93,7 +93,7 @@ func (c *ApiController) DeleteNotification() {
}
func (c *ApiController) GetUnreadNotificationNum() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var resp Response
res := object.GetUnreadNotificationNum(memberId)
@ -104,7 +104,7 @@ func (c *ApiController) GetUnreadNotificationNum() {
}
func (c *ApiController) UpdateReadStatus() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
c.Data["json"] = object.UpdateReadStatus(memberId)
c.ServeJSON()

View File

@ -58,8 +58,8 @@ func (c *ApiController) AddPlane() {
var plane object.AdminPlaneInfo
var resp Response
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}
@ -105,8 +105,8 @@ func (c *ApiController) UpdatePlane() {
var resp Response
var plane object.AdminPlaneInfo
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}
@ -134,8 +134,8 @@ func (c *ApiController) UpdatePlane() {
func (c *ApiController) DeletePlane() {
id := c.Input().Get("id")
if !object.CheckModIdentity(c.GetSessionUser()) {
c.RequireAdmin(c.GetSessionUser())
if !object.CheckModIdentity(c.GetSessionUsername()) {
c.RequireAdmin(c.GetSessionUsername())
return
}

View File

@ -22,7 +22,7 @@ import (
func (c *ApiController) UpdatePoster() {
var resp Response
if !object.CheckModIdentity(c.GetSessionUser()) {
if !object.CheckModIdentity(c.GetSessionUsername()) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
c.Data["json"] = resp
c.ServeJSON()

View File

@ -28,7 +28,7 @@ type NewReplyForm struct {
}
func (c *ApiController) GetReplies() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
topicIdStr := c.Input().Get("topicId")
limitStr := c.Input().Get("limit")
pageStr := c.Input().Get("page")
@ -77,7 +77,7 @@ func (c *ApiController) GetReply() {
}
func (c *ApiController) GetReplyWithDetails() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
idStr := c.Input().Get("id")
id := util.ParseInt(idStr)
@ -105,7 +105,7 @@ func (c *ApiController) AddReply() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
// check account status
if object.IsMuted(memberId) || object.IsForbidden(memberId) {
c.mutedAccountResp(memberId)
@ -164,7 +164,7 @@ func (c *ApiController) AddReply() {
func (c *ApiController) DeleteReply() {
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
replyInfo := object.GetReply(id)
isModerator := object.CheckModIdentity(memberId)

View File

@ -23,7 +23,7 @@ func (c *ApiController) AddSensitive() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
member := object.GetMember(memberId)
if !member.IsModerator {
resp := Response{Status: "fail", Msg: "You are not admin, you can't add sensitive words."}
@ -61,7 +61,7 @@ func (c *ApiController) DelSensitive() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
member := object.GetMember(memberId)
if !member.IsModerator {
resp := Response{Status: "fail", Msg: "You are not admin, you can't delete sensitive words."}

View File

@ -88,7 +88,7 @@ func (c *ApiController) UpdateTab() {
var resp Response
var tabInfo object.AdminTabInfo
if !object.CheckModIdentity(c.GetSessionUser()) {
if !object.CheckModIdentity(c.GetSessionUsername()) {
resp = Response{Status: "fail", Msg: "Unauthorized."}
}
@ -114,7 +114,7 @@ func (c *ApiController) UpdateTab() {
func (c *ApiController) DeleteTab() {
id := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
if !object.CheckModIdentity(memberId) {
resp := Response{Status: "fail", Msg: "Unauthorized."}

View File

@ -90,7 +90,7 @@ func (c *ApiController) GetTopicsAdmin() {
}
func (c *ApiController) GetTopic() {
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
idStr := c.Input().Get("id")
id := util.ParseInt(idStr)
@ -138,7 +138,7 @@ func (c *ApiController) AddTopic() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
// check account status
if object.IsMuted(memberId) || object.IsForbidden(memberId) {
c.mutedAccountResp(memberId)
@ -220,7 +220,7 @@ func (c *ApiController) UploadTopicPic() {
if c.RequireLogin() {
return
}
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
fileBase64 := c.Ctx.Request.Form.Get("pic")
index := strings.Index(fileBase64, ",")
if index < 0 || fileBase64[0:index] != "data:image/png;base64" {
@ -240,7 +240,7 @@ func (c *ApiController) UploadTopicPic() {
func (c *ApiController) DeleteTopic() {
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
nodeId := object.GetTopicNodeId(id)
@ -326,7 +326,7 @@ func (c *ApiController) AddTopicHitCount() {
res := object.AddTopicHitCount(topicId)
topicInfo := object.GetTopic(topicId)
hitRecord := object.BrowseRecord{
MemberId: c.GetSessionUser(),
MemberId: c.GetSessionUsername(),
RecordType: 1,
ObjectId: topicInfo.NodeId,
CreatedTime: util.GetCurrentTime(),
@ -369,7 +369,7 @@ func (c *ApiController) AddTopicBrowseCount() {
var resp Response
hitRecord := object.BrowseRecord{
MemberId: c.GetSessionUser(),
MemberId: c.GetSessionUsername(),
RecordType: 2,
ObjectId: topicId,
CreatedTime: util.GetCurrentTime(),
@ -411,7 +411,7 @@ func (c *ApiController) UpdateTopicNode() {
}
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
var form updateTopicNode
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
if err != nil {
@ -446,7 +446,7 @@ func (c *ApiController) EditContent() {
editType := c.Input().Get("editType")
var resp Response
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
if editType == "topic" {
var form editTopic
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
@ -505,7 +505,7 @@ func (c *ApiController) TopTopic() {
}
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
var resp Response
@ -550,7 +550,7 @@ func (c *ApiController) CancelTopTopic() {
}
idStr := c.Input().Get("id")
memberId := c.GetSessionUser()
memberId := c.GetSessionUsername()
id := util.ParseInt(idStr)
var resp Response

View File

@ -16,34 +16,6 @@ package controllers
import "github.com/casbin/casnode/object"
type userInfoFromGoogle struct {
Picture string `json:"picture"`
Email string `json:"email"`
}
type userEmailFromGithub struct {
Email string `json:"email"`
Primary bool `json:"primary"`
Verified bool `json:"verified"`
Visibility string `json:"visibility"`
}
type userInfoFromGithub struct {
Login string `json:"login"`
AvatarUrl string `json:"avatar_url"`
}
type userInfoFromQQ struct {
Ret int `json:"ret"`
Nickname string `json:"nickname"`
AvatarUrl string `json:"figureurl_qq_1"`
}
type userInfoFromWeChat struct {
Nickname string `json:"nickname"`
AvatarUrl string `json:"headimgurl"`
}
type GetAccessTokenRespFromWeChat struct {
AccessToken string `json:"access_token"`
ExpiresIn float64 `json:"expires_in"`
@ -60,24 +32,12 @@ type authResponse struct {
Addition string `json:"addition"`
}
type stsTokenResponse struct {
AccessKeyID string `json:"accessKeyId"`
AccessKeySecret string `json:"accessKeySecret"`
StsToken string `json:"stsToken"`
}
type newNotification struct {
ObjectId int `json:"objectId"`
NotificationType int `json:"notificationType"`
ReceiverId string `json:"receiverId"`
}
type updatePlaneInfo struct {
Id string `json:"id"`
Field string `json:"field"`
Value string `json:"value"`
}
type updateTopicNode struct {
Id int `json:"id"`
NodeId string `json:"nodeId"`
@ -98,51 +58,6 @@ type editReply struct {
EditorType string `json:"editorType"`
}
type getResetPasswordMember struct {
Username string `json:"username"`
Captcha string `json:"captcha"`
CaptchaId string `json:"captchaId"`
}
type resetPasswordPhoneResponse struct {
Username string `json:"username"`
Phone string `json:"phone"`
ValidateCodeId string `json:"validateCodeId"`
}
type resetPasswordWithPhone struct {
Method string `json:"method"`
Username string `json:"username"`
ValidateCode string `json:"validateCode"`
ValidateCodeId string `json:"validateCodeId"`
}
type verifyResetWithPhoneRes struct {
Username string `json:"username"`
ResetId int `json:"resetId"`
ResetCode string `json:"resetCode"`
}
type resetPasswordWithEmail struct {
Method string `json:"method"`
Username string `json:"username"`
Email string `json:"email"`
Url string `json:"url"`
}
type resetPasswordVerify struct {
Method string `json:"method"`
Username string `json:"username"`
Id string `json:"id"`
Code string `json:"code"`
Password string `json:"password"`
}
type resetPasswordValidateCode struct {
Method string `json:"method"`
Username string `json:"username"`
}
type fileDescribe struct {
Desc string `json:"desc"`
FileName string `json:"fileName"`

1
go.mod
View File

@ -12,6 +12,7 @@ require (
github.com/casbin/google-groups-crawler v0.1.1
github.com/chromedp/chromedp v0.6.10
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
github.com/go-sql-driver/mysql v1.5.0
github.com/gomarkdown/markdown v0.0.0-20210408062403-ad838ccf8cdd

2
go.sum
View File

@ -98,6 +98,8 @@ github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=

View File

@ -32,9 +32,10 @@ type Session struct {
}
func InitAdapter() {
adapter = NewAdapter("mysql", beego.AppConfig.String("dataSourceName"))
adapter = NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName"), beego.AppConfig.String("dbName"))
adapter.createTable()
_, err := adapter.engine.Query("update member set rename_quota = ? where rename_quota is null", DefaultRenameQuota)
_, err := adapter.Engine.Query("update member set rename_quota = ? where rename_quota is null", DefaultRenameQuota)
if err != nil {
panic(err)
}
@ -44,22 +45,24 @@ func InitAdapter() {
type Adapter struct {
driverName string
dataSourceName string
engine *xorm.Engine
dbName string
Engine *xorm.Engine
}
// finalizer is the destructor for Adapter.
func finalizer(a *Adapter) {
err := a.engine.Close()
err := a.Engine.Close()
if err != nil {
panic(err)
}
}
// NewAdapter is the constructor for Adapter.
func NewAdapter(driverName string, dataSourceName string) *Adapter {
func NewAdapter(driverName string, dataSourceName string, dbName string) *Adapter {
a := &Adapter{}
a.driverName = driverName
a.dataSourceName = dataSourceName
a.dbName = dbName
// Open the DB, create it if not existed.
a.open()
@ -71,117 +74,118 @@ func NewAdapter(driverName string, dataSourceName string) *Adapter {
}
func (a *Adapter) createDatabase() error {
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
Engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
if err != nil {
return err
}
defer engine.Close()
defer Engine.Close()
_, err = engine.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s default charset utf8 COLLATE utf8_general_ci", beego.AppConfig.String("dbName")))
_, err = Engine.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s default charset utf8 COLLATE utf8_general_ci", a.dbName))
return err
}
func (a *Adapter) open() {
if err := a.createDatabase(); err != nil {
panic(err)
if a.driverName != "postgres" {
if err := a.createDatabase(); err != nil {
panic(err)
}
}
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName+beego.AppConfig.String("dbName"))
Engine, err := xorm.NewEngine(a.driverName, a.dataSourceName+a.dbName)
if err != nil {
panic(err)
}
a.engine = engine
a.createTable()
a.Engine = Engine
}
func (a *Adapter) close() {
a.engine.Close()
a.engine = nil
a.Engine.Close()
a.Engine = nil
}
func (a *Adapter) createTable() {
err := a.engine.Sync2(new(Session))
err := a.Engine.Sync2(new(Session))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Topic))
err = a.Engine.Sync2(new(Topic))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Reply))
err = a.Engine.Sync2(new(Reply))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Member))
err = a.Engine.Sync2(new(Member))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Poster))
err = a.Engine.Sync2(new(Poster))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Node))
err = a.Engine.Sync2(new(Node))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Favorites))
err = a.Engine.Sync2(new(Favorites))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Tab))
err = a.Engine.Sync2(new(Tab))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Notification))
err = a.Engine.Sync2(new(Notification))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(BasicInfo))
err = a.Engine.Sync2(new(BasicInfo))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(Plane))
err = a.Engine.Sync2(new(Plane))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(ConsumptionRecord))
err = a.Engine.Sync2(new(ConsumptionRecord))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(BrowseRecord))
err = a.Engine.Sync2(new(BrowseRecord))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(ValidateCode))
err = a.Engine.Sync2(new(ValidateCode))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(ResetRecord))
err = a.Engine.Sync2(new(ResetRecord))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(UploadFileRecord))
err = a.Engine.Sync2(new(UploadFileRecord))
if err != nil {
panic(err)
}
err = a.engine.Sync2(new(CasbinSensitiveWord))
err = a.Engine.Sync2(new(CasbinSensitiveWord))
if err != nil {
panic(err)
}

View File

@ -36,7 +36,7 @@ type ConsumptionRecord struct {
func GetBalances() []*ConsumptionRecord {
balances := []*ConsumptionRecord{}
err := adapter.engine.Desc("created_time").Find(&balances)
err := adapter.Engine.Desc("created_time").Find(&balances)
if err != nil {
panic(err)
}
@ -46,7 +46,7 @@ func GetBalances() []*ConsumptionRecord {
func GetMemberBalances(id string, limit, offset int) []*ConsumptionRecord {
balances := []*ConsumptionRecord{}
err := adapter.engine.Desc("created_time").Where("receiver_id = ?", id).Find(&balances)
err := adapter.Engine.Desc("created_time").Where("receiver_id = ?", id).Find(&balances)
if err != nil {
panic(err)
}
@ -55,7 +55,7 @@ func GetMemberBalances(id string, limit, offset int) []*ConsumptionRecord {
}
func AddBalance(balance *ConsumptionRecord) bool {
affected, err := adapter.engine.Insert(balance)
affected, err := adapter.Engine.Insert(balance)
if err != nil {
panic(err)
}
@ -64,7 +64,7 @@ func AddBalance(balance *ConsumptionRecord) bool {
}
func GetConsumptionRecordCount() int {
count, err := adapter.engine.Count(&ConsumptionRecord{})
count, err := adapter.Engine.Count(&ConsumptionRecord{})
if err != nil {
panic(err)
}
@ -84,7 +84,7 @@ func GetConsumptionRecordId() int {
func GetMemberBalance(id string) int {
member := Member{Id: id}
existed, err := adapter.engine.Select("score_count").Get(&member)
existed, err := adapter.Engine.Select("score_count").Get(&member)
if err != nil {
panic(err)
}
@ -102,7 +102,7 @@ func UpdateMemberBalances(id string, amount int) bool {
balance := GetMemberBalance(id) + amount
member := new(Member)
member.ScoreCount = balance
affected, err := adapter.engine.Id(id).Cols("score_count").Update(member)
affected, err := adapter.Engine.Id(id).Cols("score_count").Update(member)
if err != nil {
panic(err)
}
@ -115,7 +115,7 @@ func GetMemberConsumptionRecordNum(memberId string) int {
var err error
record := new(ConsumptionRecord)
total, err = adapter.engine.Where("receiver_id = ?", memberId).Count(record)
total, err = adapter.Engine.Where("receiver_id = ?", memberId).Count(record)
if err != nil {
panic(err)
}
@ -223,7 +223,7 @@ func GetMemberConsumptionRecord(id string, limit, offset int) []*BalanceResponse
func GetThanksStatus(memberId string, id, recordType int) bool {
record := new(ConsumptionRecord)
total, err := adapter.engine.Where("consumption_type = ?", recordType).And("object_id = ?", id).And("receiver_id = ?", memberId).Count(record)
total, err := adapter.Engine.Where("consumption_type = ?", recordType).And("object_id = ?", id).And("receiver_id = ?", memberId).Count(record)
if err != nil {
panic(err)
}

View File

@ -82,7 +82,7 @@ func GetHighestOnlineNum() int {
}
info := BasicInfo{Id: "HighestOnlineNum"}
existed, err := adapter.engine.Get(&info)
existed, err := adapter.Engine.Get(&info)
if err != nil {
panic(err)
}
@ -96,7 +96,7 @@ func GetHighestOnlineNum() int {
Value: "0",
}
_, err := adapter.engine.Insert(&info)
_, err := adapter.Engine.Insert(&info)
if err != nil {
panic(err)
}
@ -109,7 +109,7 @@ func UpdateHighestOnlineNum(num int) bool {
highestOnlineNum = num
info := new(BasicInfo)
info.Value = util.IntToString(num)
affected, err := adapter.engine.Where("id = ?", "HighestOnlineNum").Cols("value").Update(info)
affected, err := adapter.Engine.Where("id = ?", "HighestOnlineNum").Cols("value").Update(info)
if err != nil {
panic(err)
}
@ -138,7 +138,7 @@ func VerifyCaptcha(id, digits string) bool {
func GetCronJobs() []*CronJob {
info := BasicInfo{Id: "CronJobs"}
existed, err := adapter.engine.Get(&info)
existed, err := adapter.Engine.Get(&info)
if err != nil {
panic(err)
}
@ -160,7 +160,7 @@ func GetCronJobs() []*CronJob {
Value: string(jobs),
}
_, err = adapter.engine.Insert(&info)
_, err = adapter.Engine.Insert(&info)
if err != nil {
panic(err)
}
@ -171,7 +171,7 @@ func GetCronJobs() []*CronJob {
func GetCronUpdateJobs() []*UpdateJob {
info := BasicInfo{Id: "CronUpdateJobs"}
existed, err := adapter.engine.Get(&info)
existed, err := adapter.Engine.Get(&info)
if err != nil {
panic(err)
}
@ -193,7 +193,7 @@ func GetCronUpdateJobs() []*UpdateJob {
Value: string(posts),
}
_, err = adapter.engine.Insert(&info)
_, err = adapter.Engine.Insert(&info)
if err != nil {
panic(err)
}
@ -204,7 +204,7 @@ func GetCronUpdateJobs() []*UpdateJob {
func GetLatestSyncedRecordId() int {
info := BasicInfo{Id: "LatestSyncedRecordId"}
existed, err := adapter.engine.Get(&info)
existed, err := adapter.Engine.Get(&info)
if err != nil {
panic(err)
}
@ -217,7 +217,7 @@ func GetLatestSyncedRecordId() int {
Value: "0",
}
_, err := adapter.engine.Insert(&info)
_, err := adapter.Engine.Insert(&info)
if err != nil {
panic(err)
}
@ -229,7 +229,7 @@ func GetLatestSyncedRecordId() int {
func UpdateLatestSyncedRecordId(id int) bool {
info := new(BasicInfo)
info.Value = util.IntToString(id)
affected, err := adapter.engine.Where("id = ?", "LatestSyncedRecordId").Cols("value").Update(info)
affected, err := adapter.Engine.Where("id = ?", "LatestSyncedRecordId").Cols("value").Update(info)
if err != nil {
panic(err)
}

View File

@ -26,7 +26,7 @@ type Favorites struct {
}
func AddFavorites(favorite *Favorites) bool {
affected, err := adapter.engine.Insert(favorite)
affected, err := adapter.Engine.Insert(favorite)
if err != nil {
panic(err)
}
@ -35,7 +35,7 @@ func AddFavorites(favorite *Favorites) bool {
}
func DeleteFavorites(memberId string, objectId string, favoritesType int) bool {
affected, err := adapter.engine.Where("favorites_type = ?", favoritesType).And("object_id = ?", objectId).And("member_id = ?", memberId).Delete(&Favorites{})
affected, err := adapter.Engine.Where("favorites_type = ?", favoritesType).And("object_id = ?", objectId).And("member_id = ?", memberId).Delete(&Favorites{})
if err != nil {
panic(err)
}
@ -44,7 +44,7 @@ func DeleteFavorites(memberId string, objectId string, favoritesType int) bool {
}
func GetFavoritesCount() int {
count, err := adapter.engine.Count(&Favorites{})
count, err := adapter.Engine.Count(&Favorites{})
if err != nil {
panic(err)
}
@ -54,7 +54,7 @@ func GetFavoritesCount() int {
func GetFavoritesStatus(memberId string, objectId string, favoritesType int) bool {
node := new(Favorites)
total, err := adapter.engine.Where("favorites_type = ?", favoritesType).And("object_id = ?", objectId).And("member_id = ?", memberId).Count(node)
total, err := adapter.Engine.Where("favorites_type = ?", favoritesType).And("object_id = ?", objectId).And("member_id = ?", memberId).Count(node)
if err != nil {
panic(err)
}
@ -64,7 +64,7 @@ func GetFavoritesStatus(memberId string, objectId string, favoritesType int) boo
func GetTopicsFromFavorites(memberId string, limit int, offset int) []*TopicWithAvatar {
favorites := []*Favorites{}
err := adapter.engine.Where("member_id = ?", memberId).And("favorites_type = ?", 1).Limit(limit, offset).Find(&favorites)
err := adapter.Engine.Where("member_id = ?", memberId).And("favorites_type = ?", 1).Limit(limit, offset).Find(&favorites)
if err != nil {
panic(err)
}
@ -82,7 +82,7 @@ func GetTopicsFromFavorites(memberId string, limit int, offset int) []*TopicWith
func GetFollowingNewAction(memberId string, limit int, offset int) []*TopicWithAvatar {
topics := []*TopicWithAvatar{}
err := adapter.engine.Table("topic").
err := adapter.Engine.Table("topic").
Join("INNER", "favorites", "favorites.object_id = topic.author").Join("INNER", "member", "member.id = topic.author").
Where("favorites.member_id = ?", memberId).And("favorites.favorites_type = ?", 2).
Desc("topic.id").
@ -98,7 +98,7 @@ func GetFollowingNewAction(memberId string, limit int, offset int) []*TopicWithA
func GetNodesFromFavorites(memberId string, limit int, offset int) []*NodeFavoritesRes {
favorites := []*Favorites{}
err := adapter.engine.Where("member_id = ?", memberId).And("favorites_type = ?", 3).Limit(limit, offset).Find(&favorites)
err := adapter.Engine.Where("member_id = ?", memberId).And("favorites_type = ?", 3).Limit(limit, offset).Find(&favorites)
if err != nil {
panic(err)
}
@ -116,7 +116,7 @@ func GetNodesFromFavorites(memberId string, limit int, offset int) []*NodeFavori
func GetNodeFavoritesNum(id string) int {
node := new(Favorites)
total, err := adapter.engine.Where("favorites_type = ?", 3).And("object_id = ?", id).Count(node)
total, err := adapter.Engine.Where("favorites_type = ?", 3).And("object_id = ?", id).Count(node)
if err != nil {
panic(err)
}
@ -126,7 +126,7 @@ func GetNodeFavoritesNum(id string) int {
func GetFollowingNum(id string) int {
member := new(Favorites)
total, err := adapter.engine.Where("favorites_type = ?", 2).And("member_id = ?", id).Count(member)
total, err := adapter.Engine.Where("favorites_type = ?", 2).And("member_id = ?", id).Count(member)
if err != nil {
panic(err)
}
@ -141,21 +141,21 @@ func GetFavoritesNum(favoritesType int, memberId string) int {
switch favoritesType {
case 1:
topic := new(Favorites)
total, err = adapter.engine.Where("favorites_type = ?", 1).And("member_id = ?", memberId).Count(topic)
total, err = adapter.Engine.Where("favorites_type = ?", 1).And("member_id = ?", memberId).Count(topic)
if err != nil {
panic(err)
}
break
case 2:
topic := new(Favorites)
total, err = adapter.engine.Table("topic").Join("INNER", "favorites", "topic.author = favorites.object_id").Where("favorites.member_id = ?", memberId).And("favorites.favorites_type = ?", 2).Count(topic)
total, err = adapter.Engine.Table("topic").Join("INNER", "favorites", "topic.author = favorites.object_id").Where("favorites.member_id = ?", memberId).And("favorites.favorites_type = ?", 2).Count(topic)
if err != nil {
panic(err)
}
break
case 3:
node := new(Favorites)
total, err = adapter.engine.Where("favorites_type = ?", 3).And("member_id = ?", memberId).Count(node)
total, err = adapter.Engine.Where("favorites_type = ?", 3).And("member_id = ?", memberId).Count(node)
if err != nil {
panic(err)
}

View File

@ -30,7 +30,7 @@ type UploadFileRecord struct {
}
func AddFileRecord(record *UploadFileRecord) (bool, int) {
affected, err := adapter.engine.Insert(record)
affected, err := adapter.Engine.Insert(record)
if err != nil {
panic(err)
}
@ -40,7 +40,7 @@ func AddFileRecord(record *UploadFileRecord) (bool, int) {
func GetFile(id int) *UploadFileRecord {
file := UploadFileRecord{Id: id}
existed, err := adapter.engine.Get(&file)
existed, err := adapter.Engine.Get(&file)
if err != nil {
panic(err)
}
@ -54,7 +54,7 @@ func GetFile(id int) *UploadFileRecord {
func GetFiles(memberId string, limit, offset int) []*UploadFileRecord {
records := []*UploadFileRecord{}
err := adapter.engine.Desc("created_time").Where("member_id = ?", memberId).And("deleted = ?", 0).Limit(limit, offset).Find(&records)
err := adapter.Engine.Desc("created_time").Where("member_id = ?", memberId).And("deleted = ?", 0).Limit(limit, offset).Find(&records)
if err != nil {
panic(err)
}
@ -67,7 +67,7 @@ func GetFilesNum(memberId string) int {
var err error
record := new(UploadFileRecord)
total, err = adapter.engine.Where("member_id = ?", memberId).And("deleted = ?", 0).Count(record)
total, err = adapter.Engine.Where("member_id = ?", memberId).And("deleted = ?", 0).Count(record)
if err != nil {
panic(err)
}
@ -78,7 +78,7 @@ func GetFilesNum(memberId string) int {
func DeleteFileRecord(id int) bool {
record := new(UploadFileRecord)
record.Deleted = true
affected, err := adapter.engine.Id(id).Cols("deleted").Update(record)
affected, err := adapter.Engine.Id(id).Cols("deleted").Update(record)
if err != nil {
panic(err)
}
@ -105,7 +105,7 @@ func AddFileViewsNum(id int) bool {
}
file.Views++
affected, err := adapter.engine.Id(id).Cols("views").Update(file)
affected, err := adapter.Engine.Id(id).Cols("views").Update(file)
if err != nil {
panic(err)
}
@ -121,7 +121,7 @@ func UpdateFileDescribe(id int, fileName, desc string) bool {
file.Desc = desc
file.FileName = fileName
affected, err := adapter.engine.Id(id).Cols("desc, file_name").Update(file)
affected, err := adapter.Engine.Id(id).Cols("desc, file_name").Update(file)
if err != nil {
panic(err)
}

View File

@ -26,7 +26,7 @@ type BrowseRecord struct {
func GetBrowseRecordNum(recordType int, objectId string) int {
record := new(BrowseRecord)
total, err := adapter.engine.Where("object_id = ?", objectId).And("record_type = ?", recordType).And("expired = ?", false).Count(record)
total, err := adapter.Engine.Where("object_id = ?", objectId).And("record_type = ?", recordType).And("expired = ?", false).Count(record)
if err != nil {
panic(err)
}
@ -35,7 +35,7 @@ func GetBrowseRecordNum(recordType int, objectId string) int {
}
func DeletedExpiredData(recordType int, date string) bool {
affected, err := adapter.engine.Where("record_type = ?", recordType).And("date < ?", date).Delete(&BrowseRecord{})
affected, err := adapter.Engine.Where("record_type = ?", recordType).And("date < ?", date).Delete(&BrowseRecord{})
if err != nil {
panic(err)
}
@ -44,7 +44,7 @@ func DeletedExpiredData(recordType int, date string) bool {
}
func AddBrowseRecordNum(record *BrowseRecord) bool {
affected, err := adapter.engine.Insert(record)
affected, err := adapter.Engine.Insert(record)
if err != nil {
panic(err)
}
@ -56,7 +56,7 @@ func ChangeExpiredDataStatus(recordType int, date string) int {
var res int
record := new(BrowseRecord)
record.Expired = true
affected, err := adapter.engine.Where("record_type = ?", recordType).And("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(record)
affected, err := adapter.Engine.Where("record_type = ?", recordType).And("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(record)
res += int(affected)
if err != nil {
panic(err)
@ -67,7 +67,7 @@ func ChangeExpiredDataStatus(recordType int, date string) int {
func GetLastRecordId() int {
record := new(BrowseRecord)
_, err := adapter.engine.Desc("id").Cols("id").Limit(1).Get(record)
_, err := adapter.Engine.Desc("id").Cols("id").Limit(1).Get(record)
if err != nil {
panic(err)
}
@ -79,7 +79,7 @@ func GetLastRecordId() int {
func UpdateHotNode(last int) int {
var record []*BrowseRecord
err := adapter.engine.Table("browse_record").Where("id > ?", last).And("record_type = ?", 1).GroupBy("object_id").Find(&record)
err := adapter.Engine.Table("browse_record").Where("id > ?", last).And("record_type = ?", 1).GroupBy("object_id").Find(&record)
if err != nil {
panic(err)
}
@ -94,7 +94,7 @@ func UpdateHotNode(last int) int {
func UpdateHotTopic(last int) int {
var record []*BrowseRecord
err := adapter.engine.Table("browse_record").Where("id > ? ", last).And("record_type = ?", 2).GroupBy("object_id").Find(&record)
err := adapter.Engine.Table("browse_record").Where("id > ? ", last).And("record_type = ?", 2).GroupBy("object_id").Find(&record)
if err != nil {
panic(err)
}

View File

@ -61,7 +61,7 @@ func (n Node) SyncFromGoogleGroup() {
AddTopic(&newTopic)
} else {
var topics []Topic
err := adapter.engine.Where("title = ? and deleted = 0", conv.Title).Find(&topics)
err := adapter.Engine.Where("title = ? and deleted = 0", conv.Title).Find(&topics)
if err != nil {
panic(err)
}
@ -126,7 +126,7 @@ func SyncAllNodeFromGoogleGroup() {
}
fmt.Println("Sync from google group started...")
var nodes []Node
err := adapter.engine.Find(&nodes)
err := adapter.Engine.Find(&nodes)
if err != nil {
panic(err)
}

View File

@ -67,7 +67,7 @@ type Member struct {
func GetMembers() []*Member {
members := []*Member{}
err := adapter.engine.Asc("created_time").Find(&members)
err := adapter.Engine.Asc("created_time").Find(&members)
if err != nil {
panic(err)
}
@ -77,7 +77,7 @@ func GetMembers() []*Member {
func GetRankingRich() []*Member {
members := []*Member{}
err := adapter.engine.Desc("score_count").Limit(25, 0).Find(&members)
err := adapter.Engine.Desc("score_count").Limit(25, 0).Find(&members)
if err != nil {
panic(err)
}
@ -87,7 +87,7 @@ func GetRankingRich() []*Member {
// GetMembersAdmin cs, us: 1 means Asc, 2 means Desc, 0 means no effect.
func GetMembersAdmin(cs, us, un string, limit int, offset int) ([]*AdminMemberInfo, int) {
members := []*Member{}
db := adapter.engine.Table("member")
db := adapter.Engine.Table("member")
var bt bytes.Buffer
@ -137,7 +137,7 @@ func GetMembersAdmin(cs, us, un string, limit int, offset int) ([]*AdminMemberIn
func GetMemberAdmin(id string) *AdminMemberInfo {
member := Member{Id: id}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -161,7 +161,7 @@ func GetMemberAdmin(id string) *AdminMemberInfo {
func GetMember(id string) *Member {
member := Member{Id: id}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -175,7 +175,7 @@ func GetMember(id string) *Member {
func GetMemberAvatar(id string) string {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("avatar").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("avatar").Get(&member)
if err != nil {
panic(err)
}
@ -188,7 +188,7 @@ func GetMemberAvatar(id string) string {
}
func GetMemberNum() int {
count, err := adapter.engine.Count(&Member{})
count, err := adapter.Engine.Count(&Member{})
if err != nil {
panic(err)
}
@ -202,7 +202,7 @@ func UpdateMember(id string, member *Member) bool {
return false
}
_, err := adapter.engine.Id(id).Cols("file_quota, status").Update(member)
_, err := adapter.Engine.Id(id).Cols("file_quota, status").Update(member)
if err != nil {
panic(err)
}
@ -216,7 +216,7 @@ func UpdateMemberInfo(id string, member *Member) bool {
return false
}
_, err := adapter.engine.Id(id).MustCols("company, bio, website, tagline, company_title, location").Update(member)
_, err := adapter.Engine.Id(id).MustCols("company, bio, website, tagline, company_title, location").Update(member)
if err != nil {
panic(err)
}
@ -237,7 +237,7 @@ func ChangeMemberEmailReminder(id, status string) bool {
member.EmailReminder = false
}
_, err := adapter.engine.Id(id).MustCols("email_reminder").Update(member)
_, err := adapter.Engine.Id(id).MustCols("email_reminder").Update(member)
if err != nil {
panic(err)
}
@ -253,7 +253,7 @@ func UpdateMemberAvatar(id string, avatar string) bool {
member := new(Member)
member.Avatar = avatar
_, err := adapter.engine.Id(id).MustCols("avatar").Update(member)
_, err := adapter.Engine.Id(id).MustCols("avatar").Update(member)
if err != nil {
panic(err)
}
@ -269,7 +269,7 @@ func UpdateMemberEditorType(id string, editorType string) bool {
member := new(Member)
member.EditorType = editorType
_, err := adapter.engine.Id(id).MustCols("editor_type").Update(member)
_, err := adapter.Engine.Id(id).MustCols("editor_type").Update(member)
if err != nil {
panic(err)
}
@ -279,7 +279,7 @@ func UpdateMemberEditorType(id string, editorType string) bool {
func GetMemberEditorType(id string) string {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("editor_type").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("editor_type").Get(&member)
if err != nil {
panic(err)
}
@ -299,7 +299,7 @@ func UpdateMemberLanguage(id string, language string) bool {
member := new(Member)
member.Language = language
_, err := adapter.engine.Id(id).MustCols("language").Update(member)
_, err := adapter.Engine.Id(id).MustCols("language").Update(member)
if err != nil {
panic(err)
}
@ -309,7 +309,7 @@ func UpdateMemberLanguage(id string, language string) bool {
func GetMemberLanguage(id string) string {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("language").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("language").Get(&member)
if err != nil {
panic(err)
}
@ -322,7 +322,7 @@ func GetMemberLanguage(id string) string {
}
func AddMember(member *Member) bool {
affected, err := adapter.engine.Insert(member)
affected, err := adapter.Engine.Insert(member)
if err != nil {
panic(err)
}
@ -332,7 +332,7 @@ func AddMember(member *Member) bool {
// DeleteMember change this function to update member status.
func DeleteMember(id string) bool {
affected, err := adapter.engine.Id(id).Delete(&Member{})
affected, err := adapter.Engine.Id(id).Delete(&Member{})
if err != nil {
panic(err)
}
@ -343,7 +343,7 @@ func DeleteMember(id string) bool {
// GetMemberMail return member's email.
func GetMemberMail(id string) string {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("email").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("email").Get(&member)
if err != nil {
panic(err)
}
@ -358,7 +358,7 @@ func GetMemberMail(id string) string {
// GetMemberEmailReminder return member's email reminder status, and his email adress.
func GetMemberEmailReminder(id string) (bool, string) {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("email_reminder, email").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("email_reminder, email").Get(&member)
if err != nil {
panic(err)
}
@ -372,7 +372,7 @@ func GetMemberEmailReminder(id string) (bool, string) {
func GetMail(email string) *Member {
member := Member{Email: email}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -386,7 +386,7 @@ func GetMail(email string) *Member {
func GetPhoneNumber(phoneNumber string) *Member {
member := Member{Phone: phoneNumber}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -400,7 +400,7 @@ func GetPhoneNumber(phoneNumber string) *Member {
func GetGoogleAccount(googleAccount string) *Member {
member := Member{GoogleAccount: googleAccount}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -414,7 +414,7 @@ func GetGoogleAccount(googleAccount string) *Member {
func GetQQAccount(qqOpenId string) *Member {
member := Member{QQOpenId: qqOpenId}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -428,7 +428,7 @@ func GetQQAccount(qqOpenId string) *Member {
func GetWechatAccount(wechatOpenId string) *Member {
member := Member{WechatOpenId: wechatOpenId}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -442,7 +442,7 @@ func GetWechatAccount(wechatOpenId string) *Member {
func GetGithubAccount(githubAccount string) *Member {
member := Member{GithubAccount: githubAccount}
existed, err := adapter.engine.Get(&member)
existed, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -455,7 +455,7 @@ func GetGithubAccount(githubAccount string) *Member {
}
func LinkMemberAccount(memberId, field, value string) bool {
affected, err := adapter.engine.Table(new(Member)).ID(memberId).Update(map[string]interface{}{field: value})
affected, err := adapter.Engine.Table(new(Member)).ID(memberId).Update(map[string]interface{}{field: value})
if err != nil {
panic(err)
}
@ -465,7 +465,7 @@ func LinkMemberAccount(memberId, field, value string) bool {
func GetMemberCheckinDate(id string) string {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("checkin_date").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("checkin_date").Get(&member)
if err != nil {
panic(err)
}
@ -481,7 +481,7 @@ func UpdateMemberCheckinDate(id, date string) bool {
member := new(Member)
member.CheckinDate = date
affected, err := adapter.engine.Id(id).MustCols("checkin_date").Update(member)
affected, err := adapter.Engine.Id(id).MustCols("checkin_date").Update(member)
if err != nil {
panic(err)
}
@ -491,7 +491,7 @@ func UpdateMemberCheckinDate(id, date string) bool {
func CheckModIdentity(memberId string) bool {
member := Member{}
existed, err := adapter.engine.Id(memberId).Cols("is_moderator").Get(&member)
existed, err := adapter.Engine.Id(memberId).Cols("is_moderator").Get(&member)
if err != nil {
panic(err)
}
@ -507,7 +507,7 @@ func UpdateMemberPassword(id, password string) bool {
member := new(Member)
member.Password = password
affected, err := adapter.engine.Id(id).MustCols("password").Update(member)
affected, err := adapter.Engine.Id(id).MustCols("password").Update(member)
if err != nil {
panic(err)
}
@ -517,7 +517,7 @@ func UpdateMemberPassword(id, password string) bool {
func GetMemberFileQuota(memberId string) int {
member := Member{}
existed, err := adapter.engine.Id(memberId).Cols("file_quota").Get(&member)
existed, err := adapter.Engine.Id(memberId).Cols("file_quota").Get(&member)
if err != nil {
panic(err)
}
@ -541,7 +541,7 @@ func MemberPasswordLogin(information, password string) string {
Email: information,
Password: password,
}
exist, err := adapter.engine.Get(&member)
exist, err := adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -553,7 +553,7 @@ func MemberPasswordLogin(information, password string) string {
Phone: information,
Password: password,
}
exist, err = adapter.engine.Get(&member)
exist, err = adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -565,7 +565,7 @@ func MemberPasswordLogin(information, password string) string {
Id: information,
Password: password,
}
exist, err = adapter.engine.Get(&member)
exist, err = adapter.Engine.Get(&member)
if err != nil {
panic(err)
}
@ -579,7 +579,7 @@ func MemberPasswordLogin(information, password string) string {
// GetMemberStatus returns member's account status, default 3(forbidden).
func GetMemberStatus(id string) int {
member := Member{}
existed, err := adapter.engine.Id(id).Cols("status").Get(&member)
existed, err := adapter.Engine.Id(id).Cols("status").Get(&member)
if err != nil {
panic(err)
}
@ -597,7 +597,7 @@ func UpdateMemberOnlineStatus(id string, onlineStatus bool, lastActionDate strin
member.OnlineStatus = onlineStatus
member.LastActionDate = lastActionDate
affected, err := adapter.engine.Id(id).MustCols("online_status, last_action_date").Update(member)
affected, err := adapter.Engine.Id(id).MustCols("online_status, last_action_date").Update(member)
if err != nil {
panic(err)
}
@ -609,7 +609,7 @@ func ExpiredMemberOnlineStatus(date string) int {
member := new(Member)
member.OnlineStatus = false
affected, err := adapter.engine.Where("online_status = ?", true).And("last_action_date < ?", date).Cols("online_status").Update(member)
affected, err := adapter.Engine.Where("online_status = ?", true).And("last_action_date < ?", date).Cols("online_status").Update(member)
if err != nil {
panic(err)
}
@ -622,7 +622,7 @@ func GetMemberOnlineNum() int {
var err error
member := new(Member)
total, err = adapter.engine.Where("online_status = ?", true).Count(member)
total, err = adapter.Engine.Where("online_status = ?", true).Count(member)
if err != nil {
panic(err)
}
@ -648,7 +648,7 @@ func ResetUsername(oldUsername string, newUsername string) string {
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)
_, err := adapter.Engine.Query("update member set rename_quota = ? where id = ?", member.RenameQuota, oldUsername)
if err != nil {
panic(err)
}
@ -669,7 +669,7 @@ func ResetUsername(oldUsername string, newUsername string) string {
{"upload_file_record", "member_id"},
}
for _, value := range updateList {
_, err = adapter.engine.Query("update "+value.Table+" set "+value.Attribute+" = ? where "+value.Attribute+" = ?", newUsername, oldUsername)
_, err = adapter.Engine.Query("update "+value.Table+" set "+value.Attribute+" = ? where "+value.Attribute+" = ?", newUsername, oldUsername)
if err != nil {
panic(err)
}
@ -683,7 +683,7 @@ func GetMemberByEmail(email string) *Member {
return nil
}
var ret Member
has, err := adapter.engine.Where("email = ?", email).Get(&ret)
has, err := adapter.Engine.Where("email = ?", email).Get(&ret)
if err != nil {
panic(err)
}
@ -737,39 +737,3 @@ func UploadFromGravatar(username, email string) string {
avatarByte, _ := ioutil.ReadAll(resp.Body)
return service.UploadAvatarToOSS(avatarByte, username)
}
func (targetMember *Member) UnbindGoogleAccount() {
targetMember.GoogleAccount = ""
_, err := adapter.engine.Id(targetMember.Id).Cols("google_account").Update(targetMember)
if err != nil {
panic(err)
}
}
func (targetMember *Member) UnbindGithubAccount() {
targetMember.GithubAccount = ""
_, err := adapter.engine.Id(targetMember.Id).Cols("github_account").Update(targetMember)
if err != nil {
panic(err)
}
}
func (targetMember *Member) UnbindWechatAccount() {
targetMember.WechatAccount = ""
targetMember.WechatOpenId = ""
targetMember.WechatVerifiedTime = ""
_, err := adapter.engine.Id(targetMember.Id).Cols("wechat_account, wechat_open_id, wechat_verified_time").Update(targetMember)
if err != nil {
panic(err)
}
}
func (targetMember *Member) UnbindQQAccount() {
targetMember.QQAccount = ""
targetMember.QQOpenId = ""
targetMember.QQVerifiedTime = ""
_, err := adapter.engine.Id(targetMember.Id).Cols("qq_account, qq_open_id, qq_verified_time").Update(targetMember)
if err != nil {
panic(err)
}
}

View File

@ -38,7 +38,7 @@ type Node struct {
func GetNodes() []*Node {
nodes := []*Node{}
err := adapter.engine.Asc("created_time").Find(&nodes)
err := adapter.Engine.Asc("created_time").Find(&nodes)
if err != nil {
panic(err)
}
@ -48,7 +48,7 @@ func GetNodes() []*Node {
func GetNode(id string) *Node {
node := Node{Id: id}
existed, err := adapter.engine.Get(&node)
existed, err := adapter.Engine.Get(&node)
if err != nil {
panic(err)
}
@ -65,7 +65,7 @@ func UpdateNode(id string, node *Node) bool {
return false
}
_, err := adapter.engine.Id(id).AllCols().Update(node)
_, err := adapter.Engine.Id(id).AllCols().Update(node)
if err != nil {
panic(err)
}
@ -75,7 +75,7 @@ func UpdateNode(id string, node *Node) bool {
}
func AddNode(node *Node) bool {
affected, err := adapter.engine.Insert(node)
affected, err := adapter.Engine.Insert(node)
if err != nil {
panic(err)
}
@ -84,7 +84,7 @@ func AddNode(node *Node) bool {
}
func DeleteNode(id string) bool {
affected, err := adapter.engine.Id(id).Delete(&Node{})
affected, err := adapter.Engine.Id(id).Delete(&Node{})
if err != nil {
panic(err)
}
@ -94,7 +94,7 @@ func DeleteNode(id string) bool {
func GetNodesNum() int {
node := new(Node)
total, err := adapter.engine.Count(node)
total, err := adapter.Engine.Count(node)
if err != nil {
panic(err)
}
@ -104,7 +104,7 @@ func GetNodesNum() int {
func GetNodeTopicNum(id string) int {
topic := new(Topic)
total, err := adapter.engine.Where("node_id = ?", id).And("deleted = ?", 0).Count(topic)
total, err := adapter.Engine.Where("node_id = ?", id).And("deleted = ?", 0).Count(topic)
if err != nil {
panic(err)
}
@ -114,7 +114,7 @@ func GetNodeTopicNum(id string) int {
func GetNodeFromTab(tab string) []*Node {
nodes := []*Node{}
err := adapter.engine.Where("tab_id = ?", tab).Desc("sorter").Find(&nodes)
err := adapter.Engine.Where("tab_id = ?", tab).Desc("sorter").Find(&nodes)
if err != nil {
panic(err)
}
@ -124,7 +124,7 @@ func GetNodeFromTab(tab string) []*Node {
func GetNodeFromPlane(plane string) []*Node {
nodes := []*Node{}
err := adapter.engine.Where("plane_id = ?", plane).Cols("id, name").Desc("sorter").Find(&nodes)
err := adapter.Engine.Where("plane_id = ?", plane).Cols("id, name").Desc("sorter").Find(&nodes)
if err != nil {
panic(err)
}
@ -138,7 +138,7 @@ func GetNodeRelation(id string) *NodeRelation {
relatedNode := []*Node{}
childNode := []*Node{}
_, err := adapter.engine.Id(id).Cols("parent_node").Get(node)
_, err := adapter.Engine.Id(id).Cols("parent_node").Get(node)
if err != nil {
panic(err)
}
@ -148,21 +148,21 @@ func GetNodeRelation(id string) *NodeRelation {
go func() {
defer wg.Done()
_, err = adapter.engine.Id(node.ParentNode).Get(parentNode)
_, err = adapter.Engine.Id(node.ParentNode).Get(parentNode)
if err != nil {
panic(err)
}
}()
go func() {
defer wg.Done()
err = adapter.engine.Table("node").Where("parent_node = ?", node.ParentNode).And("id != ?", node.ParentNode).Find(&relatedNode)
err = adapter.Engine.Table("node").Where("parent_node = ?", node.ParentNode).And("id != ?", node.ParentNode).Find(&relatedNode)
if err != nil {
panic(err)
}
}()
go func() {
defer wg.Done()
err = adapter.engine.Table("node").Where("parent_node = ?", id).And("id != ?", node.ParentNode).Find(&childNode)
err = adapter.Engine.Table("node").Where("parent_node = ?", id).And("id != ?", node.ParentNode).Find(&childNode)
if err != nil {
panic(err)
}
@ -194,7 +194,7 @@ func GetNodeNavigation() []*NodeNavigationResponse {
func GetLatestNode(limit int) []*Node {
nodes := []*Node{}
err := adapter.engine.Asc("created_time").Limit(limit).Find(&nodes)
err := adapter.Engine.Asc("created_time").Limit(limit).Find(&nodes)
if err != nil {
panic(err)
}
@ -204,7 +204,7 @@ func GetLatestNode(limit int) []*Node {
func GetHotNode(limit int) []*Node {
nodes := []*Node{}
err := adapter.engine.Desc("hot").Limit(limit).Find(&nodes)
err := adapter.Engine.Desc("hot").Limit(limit).Find(&nodes)
if err != nil {
panic(err)
}
@ -216,7 +216,7 @@ func UpdateNodeHotInfo(nodeId string, hot int) bool {
node := new(Node)
node.Hot = hot
affected, err := adapter.engine.Id(nodeId).Cols("hot").Update(node)
affected, err := adapter.Engine.Id(nodeId).Cols("hot").Update(node)
if err != nil {
panic(err)
}
@ -226,7 +226,7 @@ func UpdateNodeHotInfo(nodeId string, hot int) bool {
func GetNodeModerators(id string) []string {
node := Node{Id: id}
existed, err := adapter.engine.Cols("moderators").Get(&node)
existed, err := adapter.Engine.Cols("moderators").Get(&node)
if err != nil {
panic(err)
}
@ -240,7 +240,7 @@ func GetNodeModerators(id string) []string {
func CheckNodeModerator(memberId, nodeId string) bool {
node := Node{Id: nodeId}
existed, err := adapter.engine.Cols("moderators").Get(&node)
existed, err := adapter.Engine.Cols("moderators").Get(&node)
if err != nil {
panic(err)
}
@ -266,7 +266,7 @@ func AddNodeModerators(memberId, nodeId string) bool {
}
}
node.Moderators = append(moderators, memberId)
affected, err := adapter.engine.Id(nodeId).Cols("moderators").Update(node)
affected, err := adapter.Engine.Id(nodeId).Cols("moderators").Update(node)
if err != nil {
panic(err)
}
@ -285,7 +285,7 @@ func DeleteNodeModerators(memberId, nodeId string) bool {
}
}
node.Moderators = moderators
affected, err := adapter.engine.Id(nodeId).Cols("moderators").Update(node)
affected, err := adapter.Engine.Id(nodeId).Cols("moderators").Update(node)
if err != nil {
panic(err)
}
@ -296,7 +296,7 @@ func DeleteNodeModerators(memberId, nodeId string) bool {
func (n Node) GetAllTopicTitlesOfNode() []string {
var topics []Topic
var ret []string
err := adapter.engine.Where("node_id = ? and deleted = 0", n.Id).Find(&topics)
err := adapter.Engine.Where("node_id = ? and deleted = 0", n.Id).Find(&topics)
if err != nil {
panic(err)
}

View File

@ -36,7 +36,7 @@ type Notification struct {
}
func AddNotification(notification *Notification) bool {
affected, err := adapter.engine.Insert(notification)
affected, err := adapter.Engine.Insert(notification)
if err != nil {
panic(err)
}
@ -47,7 +47,7 @@ func AddNotification(notification *Notification) bool {
func DeleteNotification(id string) bool {
notification := new(Notification)
notification.Status = 3
affected, err := adapter.engine.Id(id).Update(notification)
affected, err := adapter.Engine.Id(id).Update(notification)
if err != nil {
panic(err)
}
@ -56,7 +56,7 @@ func DeleteNotification(id string) bool {
}
func GetNotificationCount() int {
count, err := adapter.engine.Count(&Notification{})
count, err := adapter.Engine.Count(&Notification{})
if err != nil {
panic(err)
}
@ -66,7 +66,7 @@ func GetNotificationCount() int {
func GetNotifications(memberId string, limit int, offset int) []*NotificationResponse {
notifications := []*NotificationResponse{}
err := adapter.engine.Table("notification").Join("LEFT OUTER", "member", "notification.sender_id = member.id").
err := adapter.Engine.Table("notification").Join("LEFT OUTER", "member", "notification.sender_id = member.id").
Where("notification.receiver_id = ?", memberId).And("notification.status != ?", 3).
Desc("notification.created_time").
Cols("notification.*, member.avatar").
@ -126,7 +126,7 @@ func GetNotificationNum(memberId string) int {
var err error
notification := new(Notification)
total, err = adapter.engine.Where("receiver_id = ?", memberId).And("status != ?", 3).Count(notification)
total, err = adapter.Engine.Where("receiver_id = ?", memberId).And("status != ?", 3).Count(notification)
if err != nil {
panic(err)
}
@ -139,7 +139,7 @@ func GetUnreadNotificationNum(memberId string) int {
var err error
notification := new(Notification)
total, err = adapter.engine.Where("receiver_id = ?", memberId).And("status = ?", 1).Count(notification)
total, err = adapter.Engine.Where("receiver_id = ?", memberId).And("status = ?", 1).Count(notification)
if err != nil {
panic(err)
}
@ -160,7 +160,7 @@ func GetNotificationId() int {
func UpdateReadStatus(id string) bool {
notification := new(Notification)
notification.Status = 2
affected, err := adapter.engine.Where("receiver_id = ?", id).Cols("status").Update(notification)
affected, err := adapter.Engine.Where("receiver_id = ?", id).Cols("status").Update(notification)
if err != nil {
panic(err)
}

View File

@ -29,7 +29,7 @@ type Plane struct {
func GetPlanes() []*Plane {
planes := []*Plane{}
err := adapter.engine.Asc("sorter").Where("visible = ?", 1).Find(&planes)
err := adapter.Engine.Asc("sorter").Where("visible = ?", 1).Find(&planes)
if err != nil {
panic(err)
}
@ -39,7 +39,7 @@ func GetPlanes() []*Plane {
func GetAllPlanes() []*AdminPlaneInfo {
planes := []*Plane{}
err := adapter.engine.Asc("sorter").Find(&planes)
err := adapter.Engine.Asc("sorter").Find(&planes)
if err != nil {
panic(err)
}
@ -59,7 +59,7 @@ func GetAllPlanes() []*AdminPlaneInfo {
func GetPlane(id string) *Plane {
plane := Plane{Id: id}
existed, err := adapter.engine.Get(&plane)
existed, err := adapter.Engine.Get(&plane)
if err != nil {
panic(err)
}
@ -73,7 +73,7 @@ func GetPlane(id string) *Plane {
func GetPlaneAdmin(id string) *AdminPlaneInfo {
plane := Plane{Id: id}
existed, err := adapter.engine.Get(&plane)
existed, err := adapter.Engine.Get(&plane)
if err != nil {
panic(err)
}
@ -95,7 +95,7 @@ func GetPlaneAdmin(id string) *AdminPlaneInfo {
}
func AddPlane(plane *Plane) bool {
affected, err := adapter.engine.Insert(plane)
affected, err := adapter.Engine.Insert(plane)
if err != nil {
panic(err)
}
@ -108,7 +108,7 @@ func UpdatePlane(id string, plane *Plane) bool {
return false
}
affected, err := adapter.engine.Id(id).AllCols().Update(plane)
affected, err := adapter.Engine.Id(id).AllCols().Update(plane)
if err != nil {
panic(err)
}
@ -140,7 +140,7 @@ func GetPlaneList() []*PlaneWithNodes {
}
func DeletePlane(id string) bool {
affected, err := adapter.engine.Id(id).Delete(&Plane{})
affected, err := adapter.Engine.Id(id).Delete(&Plane{})
if err != nil {
panic(err)
}
@ -150,7 +150,7 @@ func DeletePlane(id string) bool {
func GetPlaneNodesNum(id string) int {
node := new(Node)
total, err := adapter.engine.Where("plane_id = ?", id).Count(node)
total, err := adapter.Engine.Where("plane_id = ?", id).Count(node)
if err != nil {
panic(err)
}

View File

@ -23,7 +23,7 @@ type Poster struct {
}
func AddPoster(poster Poster) bool {
affected, err := adapter.engine.Insert(poster)
affected, err := adapter.Engine.Insert(poster)
if err != nil {
panic(err)
}
@ -33,7 +33,7 @@ func AddPoster(poster Poster) bool {
func GetPoster(id string) *Poster {
poster := Poster{Id: id}
existed, err := adapter.engine.Get(&poster)
existed, err := adapter.Engine.Get(&poster)
if err != nil {
panic(err)
}
@ -50,7 +50,7 @@ func UpdatePoster(id string, poster Poster) bool {
return AddPoster(poster)
}
affected, err := adapter.engine.Id(id).AllCols().Update(poster)
affected, err := adapter.Engine.Id(id).AllCols().Update(poster)
if err != nil {
panic(err)
}

View File

@ -29,7 +29,7 @@ type Reply struct {
// GetReplyCount returns all replies num so far, both deleted and not deleted.
func GetReplyCount() int {
count, err := adapter.engine.Count(&Reply{})
count, err := adapter.Engine.Count(&Reply{})
if err != nil {
panic(err)
}
@ -40,7 +40,7 @@ func GetReplyCount() int {
// GetReplies returns more information about reply of a topic.
func GetReplies(topicId int, memberId string, limit int, offset int) []*ReplyWithAvatar {
replies := []*ReplyWithAvatar{}
err := adapter.engine.Table("reply").Join("LEFT OUTER", "member", "member.id = reply.author").
err := adapter.Engine.Table("reply").Join("LEFT OUTER", "member", "member.id = reply.author").
Join("LEFT OUTER", "consumption_record", "consumption_record.object_id = reply.id and consumption_record.consumption_type = ?", 5).
Where("reply.topic_id = ?", topicId).And("reply.deleted = ?", 0).
Asc("reply.created_time").
@ -62,7 +62,7 @@ func GetReplies(topicId int, memberId string, limit int, offset int) []*ReplyWit
func GetRepliesOfTopic(topicId int) []Reply {
var ret []Reply
err := adapter.engine.Where("topic_id = ?", topicId).And("deleted = ?", 0).Find(&ret)
err := adapter.Engine.Where("topic_id = ?", topicId).And("deleted = ?", 0).Find(&ret)
if err != nil {
panic(err)
}
@ -75,7 +75,7 @@ func GetTopicReplyNum(topicId int) int {
var err error
reply := new(Reply)
total, err = adapter.engine.Where("topic_id = ?", topicId).And("deleted = ?", 0).Count(reply)
total, err = adapter.Engine.Where("topic_id = ?", topicId).And("deleted = ?", 0).Count(reply)
if err != nil {
panic(err)
}
@ -86,7 +86,7 @@ func GetTopicReplyNum(topicId int) int {
// GetLatestReplyInfo returns topic's latest reply information.
func GetLatestReplyInfo(topicId int) *Reply {
var reply Reply
exist, err := adapter.engine.Where("topic_id = ?", topicId).And("deleted = ?", false).Desc("created_time").Limit(1).Omit("content").Get(&reply)
exist, err := adapter.Engine.Where("topic_id = ?", topicId).And("deleted = ?", false).Desc("created_time").Limit(1).Omit("content").Get(&reply)
if err != nil {
panic(err)
}
@ -100,7 +100,7 @@ func GetLatestReplyInfo(topicId int) *Reply {
// GetReply returns a single reply.
func GetReply(id int) *Reply {
reply := Reply{Id: id}
existed, err := adapter.engine.Get(&reply)
existed, err := adapter.Engine.Get(&reply)
if err != nil {
panic(err)
}
@ -114,7 +114,7 @@ func GetReply(id int) *Reply {
// GetReplyWithDetails returns more information about reply, including avatar, thanks status, deletable and editable.
func GetReplyWithDetails(memberId string, id int) *ReplyWithAvatar {
reply := ReplyWithAvatar{}
existed, err := adapter.engine.Table("reply").
existed, err := adapter.Engine.Table("reply").
Join("LEFT OUTER", "member", "member.id = reply.author").
Join("LEFT OUTER", "consumption_record", "consumption_record.object_id = reply.id and consumption_record.consumption_type = ?", 5).
Id(id).Cols("reply.*, member.avatar, consumption_record.amount").Get(&reply)
@ -135,7 +135,7 @@ func GetReplyWithDetails(memberId string, id int) *ReplyWithAvatar {
/*
func GetReplyId() int {
reply := new(Reply)
_, err := adapter.engine.Desc("created_time").Omit("content").Limit(1).Get(reply)
_, err := adapter.Engine.Desc("created_time").Omit("content").Limit(1).Get(reply)
if err != nil {
panic(err)
}
@ -152,7 +152,7 @@ func UpdateReply(id int, reply *Reply) bool {
return false
}
reply.Content = FilterUnsafeHTML(reply.Content)
_, err := adapter.engine.Id(id).AllCols().Update(reply)
_, err := adapter.Engine.Id(id).AllCols().Update(reply)
if err != nil {
panic(err)
}
@ -167,7 +167,7 @@ func UpdateReplyWithLimitCols(id int, reply *Reply) bool {
return false
}
reply.Content = FilterUnsafeHTML(reply.Content)
_, err := adapter.engine.Id(id).Update(reply)
_, err := adapter.Engine.Id(id).Update(reply)
if err != nil {
panic(err)
}
@ -180,7 +180,7 @@ func UpdateReplyWithLimitCols(id int, reply *Reply) bool {
func AddReply(reply *Reply) (bool, int) {
//reply.Content = strings.ReplaceAll(reply.Content, "\n", "<br/>")
reply.Content = FilterUnsafeHTML(reply.Content)
affected, err := adapter.engine.Insert(reply)
affected, err := adapter.Engine.Insert(reply)
if err != nil {
panic(err)
}
@ -190,7 +190,7 @@ func AddReply(reply *Reply) (bool, int) {
/*
func DeleteReply(id string) bool {
affected, err := adapter.engine.Id(id).Delete(&Reply{})
affected, err := adapter.Engine.Id(id).Delete(&Reply{})
if err != nil {
panic(err)
}
@ -203,7 +203,7 @@ func DeleteReply(id string) bool {
func DeleteReply(id int) bool {
reply := new(Reply)
reply.Deleted = true
affected, err := adapter.engine.Id(id).Cols("deleted").Update(reply)
affected, err := adapter.Engine.Id(id).Cols("deleted").Update(reply)
if err != nil {
panic(err)
}
@ -214,7 +214,7 @@ func DeleteReply(id int) bool {
// GetLatestReplies returns member's latest replies.
func GetLatestReplies(author string, limit int, offset int) []*LatestReply {
replys := []*LatestReply{}
err := adapter.engine.Table("reply").Join("LEFT OUTER", "topic", "topic.id = reply.topic_id").
err := adapter.Engine.Table("reply").Join("LEFT OUTER", "topic", "topic.id = reply.topic_id").
Where("reply.author = ?", author).And("reply.deleted = ?", 0).
Desc("reply.created_time").
Cols("reply.content, reply.author, reply.created_time, topic.id, topic.node_id, topic.node_name, topic.title").
@ -232,7 +232,7 @@ func GetMemberRepliesNum(memberId string) int {
var err error
reply := new(Reply)
total, err = adapter.engine.Where("author = ?", memberId).And("deleted = ?", 0).Count(reply)
total, err = adapter.Engine.Where("author = ?", memberId).And("deleted = ?", 0).Count(reply)
if err != nil {
panic(err)
}
@ -243,7 +243,7 @@ func GetMemberRepliesNum(memberId string) int {
// GetReplyTopicTitle only returns reply's topic title.
func GetReplyTopicTitle(id int) string {
topic := Topic{Id: id}
existed, err := adapter.engine.Cols("title").Get(&topic)
existed, err := adapter.Engine.Cols("title").Get(&topic)
if err != nil {
panic(err)
}
@ -257,7 +257,7 @@ func GetReplyTopicTitle(id int) string {
// GetReplyAuthor only returns reply's topic author.
func GetReplyAuthor(id int) string {
reply := Reply{Id: id}
existed, err := adapter.engine.Cols("author").Get(&reply)
existed, err := adapter.Engine.Cols("author").Get(&reply)
if err != nil {
panic(err)
}
@ -276,7 +276,7 @@ func AddReplyThanksNum(id int) bool {
}
reply.ThanksNum++
affected, err := adapter.engine.Id(id).Cols("thanks_num").Update(reply)
affected, err := adapter.Engine.Id(id).Cols("thanks_num").Update(reply)
if err != nil {
panic(err)
}

View File

@ -15,7 +15,7 @@ type ResetRecord struct {
func GetMemberResetFrequency(memberId, date string) int {
record := new(ResetRecord)
total, err := adapter.engine.Where("member_id = ?", memberId).And("created_time > ?", date).Count(record)
total, err := adapter.Engine.Where("member_id = ?", memberId).And("created_time > ?", date).Count(record)
if err != nil {
panic(err)
}
@ -33,7 +33,7 @@ func AddNewResetRecord(resetInformation, memberId string, recordType int) (int,
Expired: false,
ValidateCode: getRandomId(20),
}
affected, err := adapter.engine.Insert(record)
affected, err := adapter.Engine.Insert(record)
if err != nil {
panic(err)
}
@ -46,7 +46,7 @@ func AddNewResetRecord(resetInformation, memberId string, recordType int) (int,
func CheckResetCodeExpired(id string) bool {
var record ResetRecord
existed, err := adapter.engine.Id(id).Get(&record)
existed, err := adapter.Engine.Id(id).Get(&record)
if err != nil {
panic(err)
}
@ -59,7 +59,7 @@ func CheckResetCodeExpired(id string) bool {
func VerifyResetInformation(id, validateCode, memberId string, recordType int) bool {
var record ResetRecord
existed, err := adapter.engine.Id(id).Get(&record)
existed, err := adapter.Engine.Id(id).Get(&record)
if err != nil {
panic(err)
}
@ -69,7 +69,7 @@ func VerifyResetInformation(id, validateCode, memberId string, recordType int) b
}
record.Expired = true
affected, err := adapter.engine.Id(id).Cols("expired").Update(record)
affected, err := adapter.Engine.Id(id).Cols("expired").Update(record)
if err != nil {
panic(err)
}
@ -83,7 +83,7 @@ func VerifyResetInformation(id, validateCode, memberId string, recordType int) b
func ExpireResetRecord(date string) int {
record := new(ResetRecord)
record.Expired = true
affected, err := adapter.engine.Where("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(record)
affected, err := adapter.Engine.Where("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(record)
if err != nil {
panic(err)
}

View File

@ -25,7 +25,7 @@ var sensitiveWords []CasbinSensitiveWord
func loadSensitiveWords() {
if len(sensitiveWords) == 0 {
err := adapter.engine.Desc("word").Find(&sensitiveWords)
err := adapter.Engine.Desc("word").Find(&sensitiveWords)
if err != nil {
panic(err)
}
@ -36,24 +36,24 @@ func AddSensitiveWord(word string) {
if IsSensitiveWord(word) {
return
}
_, err := adapter.engine.Insert(CasbinSensitiveWord{Word: word})
_, err := adapter.Engine.Insert(CasbinSensitiveWord{Word: word})
if err != nil {
panic(err)
}
sensitiveWords = nil
err = adapter.engine.Desc("word").Find(&sensitiveWords)
err = adapter.Engine.Desc("word").Find(&sensitiveWords)
if err != nil {
panic(err)
}
}
func DeleteSensitiveWord(word string) {
_, err := adapter.engine.Delete(CasbinSensitiveWord{Word: word})
_, err := adapter.Engine.Delete(CasbinSensitiveWord{Word: word})
if err != nil {
panic(err)
}
sensitiveWords = nil
err = adapter.engine.Desc("word").Find(&sensitiveWords)
err = adapter.Engine.Desc("word").Find(&sensitiveWords)
if err != nil {
panic(err)
}

View File

@ -25,7 +25,7 @@ type Tab struct {
func GetTab(id string) *Tab {
tab := Tab{Id: id}
existed, err := adapter.engine.Get(&tab)
existed, err := adapter.Engine.Get(&tab)
if err != nil {
panic(err)
}
@ -38,7 +38,7 @@ func GetTab(id string) *Tab {
}
func AddTab(tab *Tab) bool {
affected, err := adapter.engine.Insert(tab)
affected, err := adapter.Engine.Insert(tab)
if err != nil {
panic(err)
}
@ -51,7 +51,7 @@ func UpdateTab(id string, tab *Tab) bool {
return false
}
_, err := adapter.engine.Id(id).AllCols().Omit("id").Update(tab)
_, err := adapter.Engine.Id(id).AllCols().Omit("id").Update(tab)
if err != nil {
panic(err)
}
@ -61,7 +61,7 @@ func UpdateTab(id string, tab *Tab) bool {
}
func DeleteTab(id string) bool {
affected, err := adapter.engine.Id(id).Delete(&Tab{})
affected, err := adapter.Engine.Id(id).Delete(&Tab{})
if err != nil {
panic(err)
}
@ -71,7 +71,7 @@ func DeleteTab(id string) bool {
func GetHomePageTabs() []*Tab {
tabs := []*Tab{}
err := adapter.engine.Asc("sorter").Where("home_page = ?", 1).Find(&tabs)
err := adapter.Engine.Asc("sorter").Where("home_page = ?", 1).Find(&tabs)
if err != nil {
panic(err)
}
@ -81,7 +81,7 @@ func GetHomePageTabs() []*Tab {
func GetAllTabs() []*Tab {
tabs := []*Tab{}
err := adapter.engine.Asc("sorter").Find(&tabs)
err := adapter.Engine.Asc("sorter").Find(&tabs)
if err != nil {
panic(err)
}
@ -92,7 +92,7 @@ func GetAllTabs() []*Tab {
// GetTabAdmin returns more tab information for admin.
func GetTabAdmin(id string) *AdminTabInfo {
tab := Tab{Id: id}
existed, err := adapter.engine.Get(&tab)
existed, err := adapter.Engine.Get(&tab)
if err != nil {
panic(err)
}
@ -121,7 +121,7 @@ func GetTabAdmin(id string) *AdminTabInfo {
func GetAllTabsAdmin() []*AdminTabInfo {
tabs := []*Tab{}
err := adapter.engine.Asc("sorter").Find(&tabs)
err := adapter.Engine.Asc("sorter").Find(&tabs)
if err != nil {
panic(err)
}
@ -151,7 +151,7 @@ func GetAllTabsAdmin() []*AdminTabInfo {
func GetDefaultTab() string {
var tab Tab
_, err := adapter.engine.Where("home_page = ?", 1).Asc("sorter").Limit(1).Get(&tab)
_, err := adapter.Engine.Where("home_page = ?", 1).Asc("sorter").Limit(1).Get(&tab)
if err != nil {
panic(err)
}
@ -165,12 +165,12 @@ func GetNodesByTab(id string) []*Node {
num := HomePageNodeNum
if id == "all" {
err := adapter.engine.Cols("id, name").Desc("sorter").Limit(num).Find(&nodes)
err := adapter.Engine.Cols("id, name").Desc("sorter").Limit(num).Find(&nodes)
if err != nil {
panic(err)
}
} else {
err := adapter.engine.Where("tab_id = ?", id).Cols("id, name").Desc("sorter").Limit(num).Find(&nodes)
err := adapter.Engine.Where("tab_id = ?", id).Cols("id, name").Desc("sorter").Limit(num).Find(&nodes)
if err != nil {
panic(err)
}

View File

@ -45,7 +45,7 @@ type Topic struct {
}
func GetTopicCount() int {
count, err := adapter.engine.Count(&Topic{})
count, err := adapter.Engine.Count(&Topic{})
if err != nil {
panic(err)
}
@ -54,7 +54,7 @@ func GetTopicCount() int {
}
func GetTopicNum() int {
count, err := adapter.engine.Where("deleted = ?", 0).Count(&Topic{})
count, err := adapter.Engine.Where("deleted = ?", 0).Count(&Topic{})
if err != nil {
panic(err)
}
@ -64,7 +64,7 @@ func GetTopicNum() int {
func GetCreatedTopicsNum(memberId string) int {
topic := new(Topic)
total, err := adapter.engine.Where("author = ?", memberId).And("deleted = ?", 0).Count(topic)
total, err := adapter.Engine.Where("author = ?", memberId).And("deleted = ?", 0).Count(topic)
if err != nil {
panic(err)
}
@ -74,7 +74,7 @@ func GetCreatedTopicsNum(memberId string) int {
func GetTopics(limit int, offset int) []*TopicWithAvatar {
topics := []*TopicWithAvatar{}
err := adapter.engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
err := adapter.Engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
Where("topic.deleted = ?", 0).
Desc("topic.home_page_top_time").Desc("topic.last_reply_time").Desc("topic.created_time").
Cols("topic.id, topic.author, topic.node_id, topic.node_name, topic.title, topic.created_time, topic.last_reply_user, topic.last_Reply_time, topic.reply_count, topic.favorite_count, topic.deleted, topic.home_page_top_time, topic.tab_top_time, topic.node_top_time, member.avatar").
@ -101,7 +101,7 @@ func GetTopics(limit int, offset int) []*TopicWithAvatar {
// GetTopicsAdmin *sort: 1 means Asc, 2 means Desc, 0 means no effect.
func GetTopicsAdmin(usernameSearchKw, titleSearchKw, contentSearchKw, showDeletedTopic, createdTimeSort, lastReplySort, usernameSort, replyCountSort, hotSort, favCountSort string, limit int, offset int) ([]*AdminTopicInfo, int) {
topics := []*Topic{}
db := adapter.engine.Table("topic")
db := adapter.Engine.Table("topic")
// created time sort
switch createdTimeSort {
@ -195,7 +195,7 @@ func GetTopicsAdmin(usernameSearchKw, titleSearchKw, contentSearchKw, showDelete
func GetTopicWithAvatar(id int, memberId string) *TopicWithAvatar {
topic := TopicWithAvatar{}
_, err := adapter.engine.Table("topic").Id(id).Join("LEFT OUTER", "member", "member.id = topic.author").Cols("topic.*, member.avatar").Get(&topic)
_, err := adapter.Engine.Table("topic").Id(id).Join("LEFT OUTER", "member", "member.id = topic.author").Cols("topic.*, member.avatar").Get(&topic)
if err != nil {
panic(err)
}
@ -208,7 +208,7 @@ func GetTopicWithAvatar(id int, memberId string) *TopicWithAvatar {
func GetTopic(id int) *Topic {
topic := Topic{Id: id}
existed, err := adapter.engine.Get(&topic)
existed, err := adapter.Engine.Get(&topic)
if err != nil {
panic(err)
}
@ -222,7 +222,7 @@ func GetTopic(id int) *Topic {
func GetTopicBasicInfo(id int) *Topic {
topic := Topic{Id: id}
existed, err := adapter.engine.Id(id).Omit("content").Get(&topic)
existed, err := adapter.Engine.Id(id).Omit("content").Get(&topic)
if err != nil {
panic(err)
}
@ -236,7 +236,7 @@ func GetTopicBasicInfo(id int) *Topic {
func GetTopicAdmin(id int) *AdminTopicInfo {
topic := Topic{Id: id}
existed, err := adapter.engine.Get(&topic)
existed, err := adapter.Engine.Get(&topic)
if err != nil {
panic(err)
}
@ -253,7 +253,7 @@ func GetTopicAdmin(id int) *AdminTopicInfo {
func GetTopicTitle(id int) string {
topic := Topic{Id: id}
existed, err := adapter.engine.Cols("title").Get(&topic)
existed, err := adapter.Engine.Cols("title").Get(&topic)
if err != nil {
panic(err)
}
@ -267,7 +267,7 @@ func GetTopicTitle(id int) string {
func GetTopicAuthor(id int) string {
topic := Topic{Id: id}
existed, err := adapter.engine.Cols("author").Get(&topic)
existed, err := adapter.Engine.Cols("author").Get(&topic)
if err != nil {
panic(err)
}
@ -281,7 +281,7 @@ func GetTopicAuthor(id int) string {
func GetTopicNodeId(id int) string {
topic := Topic{Id: id}
existed, err := adapter.engine.Cols("node_id").Get(&topic)
existed, err := adapter.Engine.Cols("node_id").Get(&topic)
if err != nil {
panic(err)
}
@ -295,7 +295,7 @@ func GetTopicNodeId(id int) string {
func GetTopicsWithNode(nodeId string, limit int, offset int) []*NodeTopic {
topics := []*NodeTopic{}
err := adapter.engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
err := adapter.Engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
Where("topic.node_id = ?", nodeId).And("topic.deleted = ?", 0).
Desc("topic.node_top_time").Desc("topic.last_reply_time").Desc("topic.created_time").
Cols("topic.*, member.avatar").
@ -317,7 +317,7 @@ func UpdateTopic(id int, topic *Topic) bool {
return false
}
topic.Content = FilterUnsafeHTML(topic.Content)
_, err := adapter.engine.Id(id).AllCols().Update(topic)
_, err := adapter.Engine.Id(id).AllCols().Update(topic)
if err != nil {
panic(err)
}
@ -331,7 +331,7 @@ func UpdateTopicWithLimitCols(id int, topic *Topic) bool {
return false
}
topic.Content = FilterUnsafeHTML(topic.Content)
_, err := adapter.engine.Id(id).Update(topic)
_, err := adapter.Engine.Id(id).Update(topic)
if err != nil {
panic(err)
}
@ -343,7 +343,7 @@ func UpdateTopicWithLimitCols(id int, topic *Topic) bool {
// AddTopic return add topic result and topic id
func AddTopic(topic *Topic) (bool, int) {
topic.Content = FilterUnsafeHTML(topic.Content)
affected, err := adapter.engine.Insert(topic)
affected, err := adapter.Engine.Insert(topic)
if err != nil {
panic(err)
}
@ -365,7 +365,7 @@ func DeleteTopic(id string) bool {
func DeleteTopic(id int) bool {
topic := new(Topic)
topic.Deleted = true
affected, err := adapter.engine.Id(id).Cols("deleted").Update(topic)
affected, err := adapter.Engine.Id(id).Cols("deleted").Update(topic)
if err != nil {
panic(err)
}
@ -376,7 +376,7 @@ func DeleteTopic(id int) bool {
/*
func GetTopicId() int {
topic := new(Topic)
_, err := adapter.engine.Desc("created_time").Omit("content").Limit(1).Get(topic)
_, err := adapter.Engine.Desc("created_time").Omit("content").Limit(1).Get(topic)
if err != nil {
panic(err)
}
@ -389,7 +389,7 @@ func GetTopicId() int {
func GetAllCreatedTopics(author string, tab string, limit int, offset int) []*Topic {
topics := []*Topic{}
err := adapter.engine.Desc("created_time").Where("author = ?", author).And("deleted = ?", 0).Omit("content").Limit(limit, offset).Find(&topics)
err := adapter.Engine.Desc("created_time").Where("author = ?", author).And("deleted = ?", 0).Omit("content").Limit(limit, offset).Find(&topics)
if err != nil {
panic(err)
}
@ -404,7 +404,7 @@ func AddTopicHitCount(topicId int) bool {
}
topic.HitCount++
affected, err := adapter.engine.Id(topicId).Cols("hit_count").Update(topic)
affected, err := adapter.Engine.Id(topicId).Cols("hit_count").Update(topic)
if err != nil {
panic(err)
}
@ -419,7 +419,7 @@ func ChangeTopicFavoriteCount(topicId int, num int) bool {
}
topic.FavoriteCount += num
affected, err := adapter.engine.Id(topicId).Cols("favorite_count").Update(topic)
affected, err := adapter.Engine.Id(topicId).Cols("favorite_count").Update(topic)
if err != nil {
panic(err)
}
@ -434,7 +434,7 @@ func ChangeTopicReplyCount(topicId int, num int) bool {
}
topic.ReplyCount += num
affected, err := adapter.engine.Id(topicId).Cols("reply_count").Update(topic)
affected, err := adapter.Engine.Id(topicId).Cols("reply_count").Update(topic)
if err != nil {
panic(err)
}
@ -453,7 +453,7 @@ func ChangeTopicLastReplyUser(topicId int, memberId string, updateTime string) b
if len(memberId) == 0 {
topic.LastReplyTime = ""
}
affected, err := adapter.engine.Id(topicId).Cols("last_reply_user, last_reply_time").Update(topic)
affected, err := adapter.Engine.Id(topicId).Cols("last_reply_user, last_reply_time").Update(topic)
if err != nil {
panic(err)
}
@ -467,7 +467,7 @@ func GetTopicsWithTab(tab string, limit, offset int) []*TopicWithAvatar {
if tab == "all" {
topics = GetTopics(limit, offset)
} else {
err := adapter.engine.Table("topic").Join("INNER", "node", "node.id = topic.node_id").Join("LEFT OUTER", "member", "member.id = topic.author").
err := adapter.Engine.Table("topic").Join("INNER", "node", "node.id = topic.node_id").Join("LEFT OUTER", "member", "member.id = topic.author").
Where("node.tab_id = ?", tab).And("topic.deleted = ?", 0).
Desc("topic.tab_top_time").Desc("topic.last_reply_time").
Cols("topic.id, topic.author, topic.node_id, topic.node_name, topic.title, topic.created_time, topic.last_reply_user, topic.last_Reply_time, topic.reply_count, topic.favorite_count, topic.deleted, topic.home_page_top_time, topic.tab_top_time, topic.node_top_time, member.avatar").
@ -485,7 +485,7 @@ func UpdateTopicHotInfo(topicId string, hot int) bool {
topic := new(Topic)
topic.Hot = hot
affected, err := adapter.engine.Id(topicId).Cols("hot").Update(topic)
affected, err := adapter.Engine.Id(topicId).Cols("hot").Update(topic)
if err != nil {
panic(err)
}
@ -495,7 +495,7 @@ func UpdateTopicHotInfo(topicId string, hot int) bool {
func GetHotTopic(limit int) []*TopicWithAvatar {
topics := []*TopicWithAvatar{}
err := adapter.engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
err := adapter.Engine.Table("topic").Join("LEFT OUTER", "member", "member.id = topic.author").
Desc("hot").And("deleted = ? ", 0).Limit(limit).Find(&topics)
if err != nil {
panic(err)
@ -544,7 +544,7 @@ func ChangeTopicTopExpiredTime(id int, date, topType string) bool {
topic.HomePageTopTime = date
}
affected, err := adapter.engine.Id(id).Cols("tab_top_time, node_top_time, home_page_top_time").Update(topic)
affected, err := adapter.Engine.Id(id).Cols("tab_top_time, node_top_time, home_page_top_time").Update(topic)
if err != nil {
panic(err)
}
@ -555,7 +555,7 @@ func ChangeTopicTopExpiredTime(id int, date, topType string) bool {
// ExpireTopTopic searches and expires expired top topic.
func ExpireTopTopic() int {
topics := []*Topic{}
err := adapter.engine.Where("tab_top_time != ?", "").Or("node_top_time != ?", "").Or("home_page_top_time != ?", "").Cols("id, tab_top_time, node_top_time, home_page_top_time").Find(&topics)
err := adapter.Engine.Where("tab_top_time != ?", "").Or("node_top_time != ?", "").Or("home_page_top_time != ?", "").Cols("id, tab_top_time, node_top_time, home_page_top_time").Find(&topics)
if err != nil {
panic(err)
}
@ -589,7 +589,7 @@ func ExpireTopTopic() int {
func (t Topic) GetAllRepliesOfTopic() []string {
var ret []string
var replies []Reply
err := adapter.engine.Where("topic_id = ? and deleted = 0", t.Id).Find(&replies)
err := adapter.Engine.Where("topic_id = ? and deleted = 0", t.Id).Find(&replies)
if err != nil {
panic(err)
}

View File

@ -41,7 +41,7 @@ func GetNewValidateCode(information string) (string, string) {
CreatedTime: util.GetCurrentTime(),
Expired: false,
}
affected, err := adapter.engine.Insert(validateCode)
affected, err := adapter.Engine.Insert(validateCode)
if err != nil {
panic(err)
}
@ -55,7 +55,7 @@ func GetNewValidateCode(information string) (string, string) {
// CheckValidateCodeExpired checks whether the verification code has expired.
func CheckValidateCodeExpired(id string) bool {
var code ValidateCode
existed, err := adapter.engine.Id(id).Get(&code)
existed, err := adapter.Engine.Id(id).Get(&code)
if err != nil {
panic(err)
}
@ -69,7 +69,7 @@ func CheckValidateCodeExpired(id string) bool {
// VerifyValidateCode verifies validate code.
func VerifyValidateCode(id, validateCode, information string) bool {
var code ValidateCode
existed, err := adapter.engine.Id(id).Get(&code)
existed, err := adapter.Engine.Id(id).Get(&code)
if err != nil {
panic(err)
}
@ -79,7 +79,7 @@ func VerifyValidateCode(id, validateCode, information string) bool {
}
code.Expired = true
affected, err := adapter.engine.Id(id).Cols("expired").Update(code)
affected, err := adapter.Engine.Id(id).Cols("expired").Update(code)
if err != nil {
panic(err)
}
@ -94,7 +94,7 @@ func VerifyValidateCode(id, validateCode, information string) bool {
func ExpireValidateCode(date string) int {
code := new(ValidateCode)
code.Expired = true
affected, err := adapter.engine.Where("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(code)
affected, err := adapter.Engine.Where("expired = ?", 0).And("created_time < ?", date).Cols("expired").Update(code)
if err != nil {
panic(err)
}

View File

@ -108,16 +108,9 @@ func initAPI() {
beego.Router("/api/delete-node-moderators", &controllers.ApiController{}, "POST:DeleteNodeModerators")
beego.Router("/api/get-nodes-admin", &controllers.ApiController{}, "GET:GetNodesAdmin")
beego.Router("/api/signup", &controllers.ApiController{}, "POST:Signup")
beego.Router("/api/signin", &controllers.ApiController{}, "POST:Signin")
beego.Router("/api/signout", &controllers.ApiController{}, "POST:Signout")
beego.Router("/api/get-account", &controllers.ApiController{}, "GET:GetAccount")
beego.Router("/api/auth/google", &controllers.ApiController{}, "GET:AuthGoogle")
beego.Router("/api/auth/github", &controllers.ApiController{}, "GET:AuthGithub")
beego.Router("/api/auth/qq", &controllers.ApiController{}, "GET:AuthQQ")
beego.Router("/api/auth/wechat", &controllers.ApiController{}, "GET:AuthWeChat")
beego.Router("/api/reset-password", &controllers.ApiController{}, "POST:ResetPassword")
beego.Router("/api/unbind", &controllers.ApiController{}, "GET:UnbindAccount")
beego.Router("/api/add-favorites", &controllers.ApiController{}, "POST:AddFavorites")
beego.Router("/api/get-favorites", &controllers.ApiController{}, "GET:GetFavorites")

View File

@ -35,30 +35,6 @@ func InitDialer() {
dialer = gomail.NewDialer(mailConn["host"], port, mailConn["user"], mailConn["pass"])
}
// SendResetPasswordMail sends mail with reset password information.
func SendResetPasswordMail(email, memberId, url string) error {
mail := gomail.NewMessage()
name := beego.AppConfig.String("appname")
body := `Hi: ` + memberId + `, <br/><br/> 我们的系统收到一个请求
说你希望通过电子邮件重新设置你在 ` + name + ` 的密码你可以点击下面的链接开始重设密码<br/><br/><a href="` + url + `">` + url + `</a><br/><br/>
如果这个请求不是由你发起的那没问题你不用担心你可以安全地忽略这封邮件<br/><br/>
如果你有任何疑问可以回复这封邮件向我们提问<br/><br/>
<front color="#888888">` + name + `</front>`
mail.SetHeader("From", mail.FormatAddress(mailConn["user"], name))
mail.SetHeader("To", email)
mail.SetHeader("Subject", "["+name+"]"+" 重设密码") // set subject
mail.SetBody("text/html", body) // set body
if dialer == nil {
InitDialer()
}
err := dialer.DialAndSend(mail)
return err
}
// SendRegistrationMail sends mail with registration information.
func SendRegistrationMail(email, validateCode string) error {
mail := gomail.NewMessage()

47
sync/adapter.go Normal file
View File

@ -0,0 +1,47 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sync
import (
"github.com/astaxie/beego"
"github.com/casbin/casnode/auth"
"github.com/casbin/casnode/object"
_ "github.com/go-sql-driver/mysql" // db = mysql
//_ "github.com/lib/pq" // db = postgres
)
var adapter *object.Adapter
func initConfig() {
err := beego.LoadAppConfig("ini", "../conf/app.conf")
if err != nil {
panic(err)
}
initAdapter()
}
func initAdapter() {
adapter = object.NewAdapter(beego.AppConfig.String("driverName"), beego.AppConfig.String("dataSourceName"), dbName)
}
func addUser(user *auth.User) bool {
affected, err := adapter.Engine.Insert(user)
if err != nil {
panic(err)
}
return affected != 0
}

20
sync/conf.go Normal file
View File

@ -0,0 +1,20 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sync
var dbName = "casdoor"
var tableName = "user"
var orgName = "casbin-forum"

67
sync/sync.go Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sync
import (
"strconv"
"github.com/casbin/casnode/auth"
"github.com/casbin/casnode/object"
)
func createCasdoorUserFromMember(member *object.Member) *auth.User {
properties := map[string]string{}
properties["tagline"] = member.Tagline
properties["bio"] = member.Bio
properties["website"] = member.Website
properties["location"] = member.Location
properties["checkinDate"] = member.CheckinDate
properties["emailVerifiedTime"] = member.EmailVerifiedTime
properties["phoneVerifiedTime"] = member.PhoneVerifiedTime
properties["oauth_QQ_displayName"] = member.QQAccount
properties["oauth_QQ_verifiedTime"] = member.QQVerifiedTime
properties["fileQuota"] = strconv.Itoa(member.FileQuota)
properties["oauth_WeChat_displayName"] = member.WechatAccount
properties["oauth_WeChat_verifiedTime"] = member.WechatVerifiedTime
properties["editorType"] = member.EditorType
properties["renameQuota"] = strconv.Itoa(member.RenameQuota)
user := &auth.User{
Owner: "casbin-forum",
Name: member.Id,
CreatedTime: member.CreatedTime,
UpdatedTime: member.LastActionDate,
Id: strconv.Itoa(member.No),
Type: "normal-user",
Password: member.Password,
DisplayName: member.Id,
Avatar: member.Avatar,
Email: member.Email,
Phone: member.Phone,
Affiliation: member.Company,
Tag: member.CompanyTitle,
Language: member.Language,
Score: member.ScoreCount,
IsAdmin: member.IsModerator,
IsGlobalAdmin: false,
IsForbidden: false,
Github: member.GithubAccount,
Google: member.GoogleAccount,
QQ: member.QQOpenId,
WeChat: member.WechatOpenId,
Properties: properties,
}
return user
}

35
sync/sync_test.go Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sync
import (
"fmt"
"testing"
"github.com/casbin/casnode/object"
)
func TestSyncUsers(t *testing.T) {
initConfig()
initAdapter()
object.InitAdapter()
members := object.GetMembers()
for _, member := range members {
user := createCasdoorUserFromMember(member)
addUser(user)
fmt.Printf("%v\n", user)
}
}

View File

@ -25,3 +25,7 @@ func StructToJson(v interface{}) string {
return string(data)
}
func JsonToStruct(data string, v interface{}) error {
return json.Unmarshal([]byte(data), v)
}

View File

@ -22,8 +22,6 @@ import Header from "./Header";
import Footer from "./Footer";
import RightSigninBox from "./rightbar/RightSigninBox";
import RightAccountBox from "./rightbar/RightAccountBox";
import SignupBox from "./main/SignupBox";
import SigninBox from "./main/SigninBox";
import TopicBox from "./main/TopicBox";
import MemberBox from "./main/MemberBox";
import SettingsBox from "./main/SettingsBox";
@ -52,10 +50,9 @@ import RightHotNodeBox from "./rightbar/RightHotNodeBox";
import RightHotTopicBox from "./rightbar/RightHotTopicBox";
import MoveTopicNodeBox from "./main/MoveTopicNodeBox";
import EditBox from "./main/EditBox";
import ForgotBox from "./main/ForgotBox";
import FilesBox from "./main/FilesBox";
import RankingRichBox from "./main/RankingRichBox";
import NewMember from "./main/NewMember"
import NewMember from "./main/NewMember";
import AdminHomepage from "./admin/AdminHomepage";
import AdminNode from "./admin/AdminNode";
import AdminTab from "./admin/AdminTab";
@ -68,7 +65,10 @@ import i18next from "i18next";
import "./node.css";
import "./i18n";
import * as FavoritesBackend from "./backend/FavoritesBackend";
import { scoreConverter } from "./main/Tools";
import * as Auth from "./auth/Auth";
import * as Conf from "./Conf";
import AuthCallback from "./auth/AuthCallback";
class App extends Component {
constructor(props) {
@ -84,6 +84,7 @@ class App extends Component {
};
Setting.initServerUrl();
Auth.initAuthWithConfig(Conf.AuthConfig);
Setting.initFullClientUrl();
Setting.initBrowserType();
this.getNodeBackground = this.getNodeBackground.bind(this);
@ -155,6 +156,7 @@ class App extends Component {
const pcBrowser = Setting.PcBrowser;
return (
<Switch>
<Route exact path="/callback" component={AuthCallback} />
<Route exact path="/">
{pcBrowser ? null : (
<RightCheckinBonusBox account={this.state.account} />
@ -167,36 +169,6 @@ class App extends Component {
<NodeNavigationBox />
</div>
</Route>
<Route exact path="/signup">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<SignupBox
onSignout={this.onSignout.bind(this)}
refreshAccount={this.getAccount.bind(this)}
/>
</div>
</Route>
<Route exact path="/signup/:signupMethod">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<SignupBox
account={this.state.account}
onSignout={this.onSignout.bind(this)}
refreshAccount={this.getAccount.bind(this)}
/>
</div>
</Route>
<Route exact path="/signin">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<SigninBox
onSignin={this.onSignin.bind(this)}
onSignout={this.onSignout.bind(this)}
/>
{pcBrowser ? null : <div className="sep5" />}
{pcBrowser ? null : <RightSigninBox />}
</div>
</Route>
<Route exact path="/signout">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
@ -352,12 +324,6 @@ class App extends Component {
<EditBox account={this.state.account} />
</div>
</Route>
<Route exact path="/forgot">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<ForgotBox account={this.state.account} />
</div>
</Route>
<Route exact path="/i">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
@ -426,10 +392,10 @@ class App extends Component {
</div>
</Route>
<Route exact path="/admin/poster">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<AdminPoster/>
</div>
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<AdminPoster />
</div>
</Route>
<Route exact path="/admin/member">
<div id={pcBrowser ? "Main" : ""}>
@ -440,7 +406,7 @@ class App extends Component {
<Route exact path="/admin/member/new">
<div id={pcBrowser ? "Main" : ""}>
{pcBrowser ? <div className="sep20" /> : null}
<NewMember/>
<NewMember />
</div>
</Route>
<Route exact path="/admin/member/edit/:memberId">

View File

@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
export const AuthConfig = {
// serverUrl: "https://door.casbin.com",
serverUrl: "http://localhost:7001",
clientId: "014ae4bd048734ca2dea",
appName: "app-casbin-forum",
organizationName: "casbin-forum",
};
export const AuthState = "casnode";
export const GoogleClientId = "";

View File

@ -19,6 +19,7 @@ import * as Setting from "./Setting";
import * as Conf from "./Conf";
import { withRouter, Link } from "react-router-dom";
import i18next from "i18next";
import * as Auth from "./auth/Auth";
class Header extends React.Component {
constructor(props) {
@ -117,13 +118,13 @@ class Header extends React.Component {
{i18next.t("general:Home")}
</Link>
&nbsp;&nbsp;&nbsp;
<Link to="/signup" className="top">
<a href={Auth.getSignupUrl()} className="top">
{i18next.t("general:Sign Up")}
</Link>
</a>
&nbsp;&nbsp;&nbsp;
<Link to="/signin" className="top">
<a href={Auth.getSigninUrl()} className="top">
{i18next.t("general:Sign In")}
</Link>
</a>
</td>
);
} else {

57
web/src/auth/Auth.js Normal file
View File

@ -0,0 +1,57 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { trim } from "./Util";
export let authConfig = {
serverUrl: "http://example.com", // your Casdoor URL, like the official one: https://door.casbin.com
clientId: "xxx", // your Casdoor OAuth Client ID
appName: "app-example", // your Casdoor application name, like: "app-built-in"
organizationName: "org-example", // your Casdoor organization name, like: "built-in"
};
export function initAuthWithConfig(config) {
authConfig = config;
}
export function getSignupUrl() {
return `${trim(authConfig.serverUrl)}/signup/${authConfig.appName}`;
}
export function getSigninUrl() {
const redirectUri = `${window.location.origin}/callback`;
const scope = "read";
const state = authConfig.appName;
return `${trim(authConfig.serverUrl)}/login/oauth/authorize?client_id=${
authConfig.clientId
}&response_type=code&redirect_uri=${redirectUri}&scope=${scope}&state=${state}`;
}
export function getUserProfileUrl(userName, account) {
let param = "";
if (account !== undefined && account !== null) {
param = `?access_token=${account.accessToken}`;
}
return `${trim(authConfig.serverUrl)}/users/${
authConfig.organizationName
}/${userName}${param}`;
}
export function getMyProfileUrl(account) {
let param = "";
if (account !== undefined && account !== null) {
param = `?access_token=${account.accessToken}`;
}
return `${trim(authConfig.serverUrl)}/account${param}`;
}

View File

@ -0,0 +1,81 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import { Button, Result, Spin } from "antd";
import { withRouter } from "react-router-dom";
import * as AccountBackend from "../backend/AccountBackend";
import * as Util from "./Util";
import { signin } from "../backend/AccountBackend";
class AuthCallback extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
msg: null,
};
}
// eslint-disable-next-line react/no-deprecated
componentWillMount() {
this.login();
}
login() {
const params = new URLSearchParams(this.props.location.search);
AccountBackend.signin(params.get("code"), params.get("state")).then(
(res) => {
if (res.status === "ok") {
Util.showMessage("success", `Logged in successfully`);
Util.goToLink("/");
} else {
this.setState({
msg: res.msg,
});
}
}
);
}
render() {
return (
<div style={{ textAlign: "center" }}>
{this.state.msg === null ? (
<Spin
size="large"
tip="Signing in..."
style={{ paddingTop: "10%" }}
/>
) : (
<div style={{ display: "inline" }}>
<Result
status="error"
title="Login Error"
subTitle={this.state.msg}
extra={[
<Button type="primary" key="details">
Details
</Button>,
<Button key="help">Help</Button>,
]}
/>
</div>
)}
</div>
);
}
}
export default withRouter(AuthCallback);

46
web/src/auth/Util.js Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2021 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { message } from "antd";
export function goToLink(link) {
window.location.href = link;
}
export function showMessage(type, text) {
if (type === "success") {
message.success(text);
} else if (type === "error") {
message.error(text);
}
}
export function trim(str, ch) {
if (str === undefined) {
return undefined;
}
let start = 0;
let end = str.length;
while (start < end && str[start] === ch) {
++start;
}
while (end > start && str[end - 1] === ch) {
--end;
}
return start > 0 || end < str.length ? str.substring(start, end) : str;
}

View File

@ -21,14 +21,6 @@ export function getAccount() {
}).then((res) => res.json());
}
export function signup(values) {
return fetch(`${Setting.ServerUrl}/api/signup`, {
method: "POST",
credentials: "include",
body: JSON.stringify(values),
}).then((res) => res.json());
}
export function signin(values) {
return fetch(`${Setting.ServerUrl}/api/signin`, {
method: "POST",
@ -51,14 +43,6 @@ export function getStsToken() {
}).then((res) => res.json());
}
export function resetPassword(step, values) {
return fetch(`${Setting.ServerUrl}/api/reset-password?step=${step}`, {
method: "POST",
credentials: "include",
body: JSON.stringify(values),
}).then((res) => res.json());
}
export function resetUsername(newUsername) {
return fetch(
`${Setting.ServerUrl}/api/reset-member-username?new=${newUsername}`,
@ -68,10 +52,3 @@ export function resetUsername(newUsername) {
}
).then((res) => res.json());
}
export function unbindAccount(type) {
return fetch(`${Setting.ServerUrl}/api/unbind?type=${type}`, {
method: "GET",
credentials: "include",
}).then((res) => res.json());
}

View File

@ -1,696 +0,0 @@
// Copyright 2020 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import * as Setting from "../Setting";
import { withRouter, Link } from "react-router-dom";
import * as BasicBackend from "../backend/BasicBackend";
import * as AccountBackend from "../backend/AccountBackend";
import i18next from "i18next";
class ForgotBox extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
objectId: props.match.params.id,
editType: props.match.params.editType,
step: 1,
editObject: [],
nodes: [],
form: {},
message: "",
method: "",
code: "",
username: "",
showTab: false,
getValidateCode: false,
Method_LIST: [
{ label: "Phone", value: "phone" },
{ label: "Email", value: "email" },
],
};
const params = new URLSearchParams(this.props.location.search);
this.state.method = params.get("method");
this.state.code = params.get("code");
this.state.username = params.get("username");
this.state.id = params.get("id");
if (
this.state.code !== undefined &&
this.state.code !== null &&
this.state.code.length !== 0
) {
this.state.step = 5;
}
}
componentDidMount() {
this.initForm();
this.getCaptcha();
}
initForm() {
let form = this.state.form;
form["step"] = this.state.step;
if (this.state.step === 5) {
form["method"] = this.state.method;
form["code"] = this.state.code;
form["id"] = this.state.id;
form["username"] = this.state.username;
}
this.setState({
form: form,
});
}
getCaptcha() {
if (this.state.step !== 1) {
return;
}
BasicBackend.getCaptcha().then((res) => {
this.setState(
{
captcha: res?.data,
captchaId: res?.data2,
},
() => {
this.updateFormField("captchaId", this.state.captchaId);
}
);
});
}
clearForm() {
this.setState({
form: {},
});
}
getValidateCode() {
AccountBackend.resetPassword(7, this.state.form).then((res) => {
if (res?.status === "ok") {
this.setState(
{
validateCodeId: res?.data,
getValidateCode: true,
},
() => {
this.updateFormField("validateCodeId", this.state.validateCodeId);
}
);
} else {
this.setState({
message: res?.msg,
});
}
});
}
getAccountInfo() {
if (
this.state.form.username === undefined ||
this.state.form.username.length === 0
) {
this.setState({
message: i18next.t("error:Please input username"),
});
return;
}
if (
this.state.form.captcha === undefined ||
this.state.form.captcha.length === 0
) {
this.setState({
message: i18next.t("error:Please input captcha"),
});
return;
}
AccountBackend.resetPassword(this.state.step, this.state.form).then(
(res) => {
if (res?.status === "ok") {
let method = res?.data;
if (res?.data === "both") {
method = "phone";
this.setState({
showTab: true,
});
}
let message = "";
let step;
if (method === "phone") {
step = 2;
} else {
step = 3;
}
this.setState(
{
step: step,
username: this.state.form.username,
method: method,
message: message,
resetInfo: res?.data2,
form: {},
},
() => {
let form = {};
form["step"] = this.state.step;
form["method"] = this.state.method;
form["username"] = this.state.username;
if (res?.data === "phone") {
form["validateCodeId"] = res?.data2.validateCodeId;
} else {
form["url"] = Setting.ClientUrl;
}
this.setState({
form: form,
});
}
);
} else {
this.setState({
message: res?.msg,
});
}
}
);
}
changeTab(method) {
let step;
if (method === "phone") {
step = 2;
} else {
step = 3;
}
this.setState({
step: step,
method: method,
});
}
postVerification() {
if (this.state.step === 2) {
if (
this.state.form.validateCode === undefined ||
this.state.form.validateCode.length === 0
) {
this.setState({
message: i18next.t("error:Please input validate code"),
});
return;
}
} else {
if (
this.state.form?.email === undefined ||
this.state.form?.email.length === 0
) {
this.setState({
message: i18next.t("error:Please input email"),
});
return;
}
}
AccountBackend.resetPassword(this.state.step, this.state.form).then(
(res) => {
if (res?.status === "ok") {
if (res?.data === "phone") {
let method = res?.data;
let code = res?.data2.resetCode;
let id = res?.data2.resetId;
let username = res?.data2.username;
this.props.history.push(
`/forgot?method=${method}&id=${id}&code=${code}&username=${username}`
);
return;
}
this.setState({
step: 4,
email: res?.data2,
});
} else {
this.setState({
message: res?.msg,
});
}
}
);
}
postResetPassword() {
if (
this.state.form.password === undefined ||
this.state.form.password.length === 0
) {
this.setState({
message: i18next.t("error:Please input your new password"),
});
return;
}
if (this.state.form?.password !== this.state.form?.passwordAgain) {
this.setState({
message: i18next.t("error:The two passwords are different"),
});
return;
}
AccountBackend.resetPassword(this.state.step, this.state.form).then(
(res) => {
if (res?.status === "ok") {
this.setState({
step: 6,
showTab: false,
});
} else {
this.setState({
message: res?.msg,
showTab: false,
});
}
}
);
}
updateFormField(key, value) {
let form = this.state.form;
form[key] = value;
this.setState({
form: form,
});
}
clearMessage() {
this.setState({
message: "",
});
}
renderProblem() {
let problems = [];
if (this.state.message !== "") {
problems.push(i18next.t(`error:${this.state.message}`));
}
if (problems.length === 0) {
return null;
}
return (
<div className="problem" onClick={() => this.clearMessage()}>
{i18next.t(
"error:Please resolve the following issues before submitting"
)}
<ul>
{problems.map((problem, i) => {
return <li>{problem}</li>;
})}
</ul>
</div>
);
}
renderMethodList(item) {
return (
<a
onClick={() => this.changeTab(item.value)}
href="javascript:void(0);"
className={this.state.method === item.value ? "tab_current" : "tab"}
>
{item.label}
</a>
);
}
render() {
switch (this.state.step) {
case 2:
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t("forgot:Reset password by phone")}
</div>
{this.state.showTab ? (
<div className="cell">
{this.state.Method_LIST.map((item) => {
return this.renderMethodList(item);
})}
</div>
) : null}
{this.renderProblem()}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right">
<span className="gray">
{i18next.t("forgot:Username")}
</span>
</td>{" "}
<td width="auto" align="left">
<span className="gray">{this.state.username}</span>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
{this.state.getValidateCode ? (
<span className="gray">
{i18next.t(
"forgot:The verification code has been sent to the mobile phone"
)}{" "}
{this.state.resetInfo?.phone}{" "}
{i18next.t(
"forgot:, please enter it within 20 minutes and do not leave the interface"
)}
</span>
) : (
<span>
<a href="#;" onClick={() => this.getValidateCode()}>
{i18next.t("signup:Click to send validate code")}
</a>
</span>
)}
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t(":Validate Code")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="validateCode"
maxLength="32"
onChange={(event) =>
this.updateFormField(
"validateCode",
event.target.value
)
}
autoComplete="off"
/>
<span className="negative"> *</span>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<input type="hidden" name="once" />
<input
type="submit"
className="super normal button"
onClick={() => this.postVerification()}
value={i18next.t("forgot:Continue")}
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
case 3:
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t("forgot:Reset password by email")}
</div>
{this.state.showTab ? (
<div className="cell">
{this.state.Method_LIST.map((item) => {
return this.renderMethodList(item);
})}
</div>
) : null}
{this.renderProblem()}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right">
<span className="gray">
{i18next.t("forgot:Username")}
</span>
</td>{" "}
<td width="auto" align="left">
<span className="gray">{this.state.username}</span>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("forgot:Mail")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="u"
value={this.state.form?.email}
onChange={(event) =>
this.updateFormField("email", event.target.value)
}
/>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<input type="hidden" name="once" />
<input
type="submit"
className="super normal button"
onClick={() => this.postVerification()}
value={i18next.t("forgot:Continue")}
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
case 4:
return (
<div class="box">
<div class="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span class="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t("forgot:Reset password by email")}
</div>
<div class="cell">
{i18next.t(
"forgot:An email containing instructions for resetting your password has been sent to your registered mailbox. Follow the instructions in the email to reset your password."
)}
</div>
<div class="inner">
<Link to="/">{i18next.t("forgot:Back to homepage")}</Link>
</div>
</div>
);
case 5:
return (
<div>
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t(`forgot:Reset password by ${this.state.method}`)}
</div>
{this.renderProblem()}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<span className="gray">
{i18next.t("forgot:Reset password for account")}{" "}
{this.state.username}{" "}
{i18next.t("forgot:重新设置密码")}
</span>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("forgot:New password")}
</td>
<td width="auto" align="left">
<input
type="password"
className="sl"
name="new"
value={this.state.form?.password}
onChange={(event) =>
this.updateFormField("password", event.target.value)
}
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("forgot:Password again")}
</td>
<td width="auto" align="left">
<input
type="password"
className="sl"
name="again"
value={this.state.form?.passwordAgain}
onChange={(event) =>
this.updateFormField(
"passwordAgain",
event.target.value
)
}
/>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<input
type="submit"
className="super normal button"
onClick={() => this.postResetPassword()}
value={i18next.t("forgot:Continue")}
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
);
case 6:
return (
<div class="box">
<div class="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span class="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t("forgot:Password reset complete")}
</div>
<div class="cell">
{i18next.t(
"forgot:The password reset is complete. You can now log in with the new password."
)}
</div>
<div class="caution">
<input
type="button"
onClick={() => this.props.history.push("/signin")}
class="super normal button"
value={i18next.t("forgot:Log in now")}
/>
</div>
</div>
);
}
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
{i18next.t("forgot:Reset Password")}
</div>
{this.renderProblem()}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right">
{i18next.t("forgot:Username")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="u"
value={this.state.form?.username}
onChange={(event) =>
this.updateFormField("username", event.target.value)
}
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("login:Are you a bot?")}{" "}
</td>
<td width="200" align="left">
<div
style={{
backgroundImage: `url('data:image/png;base64,${this.state.captcha}')`,
backgroundRepeat: "no-repeat",
width: "auto",
height: "80px",
borderRadius: "3px",
border: "1px solid #ccc",
}}
/>
<div className="sep10" />
<input
type="text"
className="sl"
name="captcha"
value={this.state.form.captcha}
onChange={(event) => {
this.updateFormField("captcha", event.target.value);
}}
autoCorrect="off"
spellCheck="false"
autoCapitalize="off"
placeholder={i18next.t(
"login:Please enter the verification code in the picture above"
)}
/>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<input type="hidden" name="once" />
<input
type="submit"
className="super normal button"
onClick={() => this.getAccountInfo()}
value={i18next.t("forgot:Continue")}
/>
</td>
</tr>
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<span className="gray">
{i18next.t(
"forgot:You can reset the password at most 2 times within 24 hours."
)}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
}
export default withRouter(ForgotBox);

View File

@ -108,27 +108,27 @@ class SettingsBox extends React.Component {
}
postUsername() {
const name = this.newUsername();
AccountBackend.signup(name)
.then((res) => {
if (res.status === "ok") {
Setting.showMessage(
"success",
i18next.t("setting:Set username success")
);
window.location.href = "/";
} else {
Setting.showMessage(
"error",
`${i18next.t("setting:Set username failed")}: ${i18next.t(
"setting:" + res.msg
)}`
);
}
})
.catch((error) => {
Setting.showMessage("error", `setting:Set username failed${error}`);
});
// const name = this.newUsername();
// AccountBackend.signup(name)
// .then((res) => {
// if (res.status === "ok") {
// Setting.showMessage(
// "success",
// i18next.t("setting:Set username success")
// );
// window.location.href = "/";
// } else {
// Setting.showMessage(
// "error",
// `${i18next.t("setting:Set username failed")}: ${i18next.t(
// "setting:" + res.msg
// )}`
// );
// }
// })
// .catch((error) => {
// Setting.showMessage("error", `setting:Set username failed${error}`);
// });
}
handleUsernameChange(e) {
@ -286,24 +286,7 @@ class SettingsBox extends React.Component {
}
renderAccountOptions(accountType) {
return (
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<a
onClick={() =>
AccountBackend.unbindAccount(accountType).then((res) => {
if (res.status !== "ok") alert(res.msg);
else window.location.reload();
})
}
href="javascript:void(0);"
>
{i18next.t("setting:Unbind Account")}
</a>
</td>
</tr>
);
return null;
}
render() {

View File

@ -1,278 +0,0 @@
// Copyright 2020 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import Header from "./Header";
import * as AccountBackend from "../backend/AccountBackend";
import * as BasicBackend from "../backend/BasicBackend";
import * as Setting from "../Setting";
import { withRouter, Link } from "react-router-dom";
import i18next from "i18next";
class SigninBox extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
form: {},
isTypingStarted: false,
problem: [],
message: "",
captcha: "",
captchaId: "",
};
}
componentDidMount() {
this.getCaptcha();
}
getCaptcha() {
BasicBackend.getCaptcha().then((res) => {
this.setState(
{
captcha: res?.data,
captchaId: res?.data2,
},
() => {
this.updateFormField("captchaId", this.state.captchaId);
}
);
});
}
updateFormField(key, value) {
let form = this.state.form;
form[key] = value;
this.setState({
form: form,
isTypingStarted: true,
});
}
onSignin(event) {
event.preventDefault();
AccountBackend.signin(this.state.form).then((res) => {
if (res.status === "ok") {
this.props.onSignin();
this.props.history.push("/");
} else {
this.setState({
message: res.msg,
});
this.getCaptcha();
}
});
}
signOut() {
if (!window.confirm(i18next.t("signout:Are you sure to log out?"))) {
return;
}
AccountBackend.signout().then((res) => {
if (res.status === "ok") {
this.props.onSignout();
this.props.history.push("/signout");
} else {
this.props.history.push("/signout");
}
});
}
clearMessage() {
this.setState({
message: "",
});
}
renderProblem() {
if (!this.state.isTypingStarted) {
return null;
}
let problems = [];
if (this.state.form.username === "") {
problems.push(i18next.t("error:Please input username"));
}
if (this.state.form.password === "") {
problems.push(i18next.t("error:Please input password"));
}
if (this.state.message !== "") {
problems.push(this.state.message);
}
if (problems.length === 0) {
return null;
}
return (
<div className="problem" onClick={this.clearMessage.bind(this)}>
{i18next.t(
"error:Please resolve the following issues before submitting"
)}
<ul>
{problems.map((problem, i) => {
if (problem === "Please sign out before sign in") {
return (
<li>
{i18next.t(`error:${this.state.message}`)} &nbsp;{" "}
<a href="#;" onClick={() => this.signOut()}>
{i18next.t("signout:Click to sign out")}
</a>
</li>
);
}
return <li>{i18next.t(`error:${problem}`)}</li>;
})}
</ul>
</div>
);
}
renderMessage() {
if (this.state.message === "" || this.state.message === "Captcha error") {
return null;
}
return (
<div className="message" onClick={this.clearMessage.bind(this)}>
<li className="fa fa-exclamation-triangle" />
&nbsp;{" "}
{i18next.t(
"error:We had a problem when you signed in, please try again"
)}
</div>
);
}
render() {
return (
<div className="box">
<Header item="Sign In" />
{this.renderProblem()}
{this.renderMessage()}
<div className="cell">
<form onSubmit={this.onSignin}>
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right">
{i18next.t("general:Username")}
</td>
<td width="auto" align="left">
<input
type="text"
value={this.state.form.information}
onChange={(event) => {
this.updateFormField("information", event.target.value);
}}
className="sl"
name="username"
autoFocus="autofocus"
autoCorrect="off"
spellCheck="false"
autoCapitalize="off"
placeholder={i18next.t(
"general:Username, email address or phone number"
)}
style={{ width: Setting.PcBrowser ? "280px" : "100%" }}
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("general:Password")}
</td>
<td width="auto" align="left">
<input
type="password"
value={this.state.form.password}
onChange={(event) => {
this.updateFormField("password", event.target.value);
}}
className="sl"
name="password"
autoCorrect="off"
spellCheck="false"
autoCapitalize="off"
style={{ width: Setting.PcBrowser ? "280px" : "100%" }}
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("login:Are you a bot?")}{" "}
</td>
<td width="auto" align="left">
<div
style={{
backgroundImage: `url('data:image/png;base64,${this.state.captcha}')`,
backgroundRepeat: "no-repeat",
width: Setting.PcBrowser ? "320px" : "100%",
height: "80px",
borderRadius: "3px",
border: "1px solid #ccc",
}}
/>
<div className="sep10" />
<input
type="text"
className="sl"
name="captcha"
value={this.state.form.captcha}
onChange={(event) => {
this.updateFormField("captcha", event.target.value);
}}
autoCorrect="off"
spellCheck="false"
autoCapitalize="off"
placeholder={i18next.t(
"login:Please enter the verification code in the picture above"
)}
/>
</td>
</tr>
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<input type="hidden" value="83861" name="once" />
<input
type="submit"
className="super normal button"
value={i18next.t("general:Sign In")}
onClick={(event) => this.onSignin(event)}
/>
</td>
</tr>
<tr>
<td width="120" align="right" />
<td width="auto" align="left">
<Link to="/forgot">
{i18next.t("general:Forgot Password")}
</Link>
</td>
</tr>
</tbody>
</table>
<input type="hidden" value="/signup" name="next" />
</form>
</div>
</div>
);
}
}
export default withRouter(SigninBox);

View File

@ -1,674 +0,0 @@
// Copyright 2020 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import React from "react";
import { withRouter, Link } from "react-router-dom";
import * as Setting from "../Setting";
import Header from "./Header";
import * as Conf from "../Conf";
import * as AccountBackend from "../backend/AccountBackend";
import * as BasicBackend from "../backend/BasicBackend";
import "../Signup.css";
import "./const";
import Select2 from "react-select2-wrapper";
import { Area_Code } from "./const";
import i18next from "i18next";
class SignupBox extends React.Component {
constructor(props) {
super(props);
this.state = {
classes: props,
signupMethod: props.match.params.signupMethod,
code: "",
form: {},
counting: false,
sendStatus: false,
showValidateCode: false,
message: "",
};
}
getGoogleAuthCode() {
window.location.href = `${Conf.GoogleOauthUri}?client_id=${Conf.GoogleClientId}&redirect_uri=${Setting.ClientUrl}/callback/google&scope=${Conf.GoogleAuthScope}&response_type=code&state=${Conf.AuthState}`;
}
getGithubAuthCode() {
window.location.href = `${Conf.GithubOauthUri}?client_id=${Conf.GithubClientId}&redirect_uri=${Setting.ClientUrl}/callback/github&scope=${Conf.GithubAuthScope}&response_type=code&state=${Conf.AuthState}`;
}
componentDidMount() {
this.initPostForm();
}
componentWillReceiveProps(newProps) {
if (newProps.location !== this.props.location) {
this.setState({
signupMethod: newProps.match.params.signupMethod,
});
this.initPostForm();
}
}
initPostForm() {
let form = this.state.form;
form["areaCode"] = Area_Code[0].value;
if (this.state.signupMethod === "sms") {
form["method"] = "phone";
} else {
form["method"] = "email";
}
this.setState({
form: form,
});
}
updateFormField(key, value) {
let form = this.state.form;
form[key] = value;
this.setState({
form: form,
});
}
countDown() {
const { count } = this.state;
if (count === 1) {
this.setState({
count: 5,
counting: false,
sendStatus: false,
});
} else {
this.setState({
count: count - 1,
});
setTimeout(this.countDown.bind(this), 1000);
}
}
signOut() {
if (!window.confirm(i18next.t("signout:Are you sure to log out?"))) {
return;
}
AccountBackend.signout().then((res) => {
if (res.status === "ok") {
this.props.onSignout();
this.props.history.push("/signout");
} else {
this.props.history.push("/signout");
}
});
}
clearMessage() {
this.setState({
message: "",
});
}
renderProblem() {
let problems = [];
if (this.state.message !== "") {
problems.push(this.state.message);
}
if (problems.length === 0) {
return null;
}
return (
<div className="problem" onClick={() => this.clearMessage()}>
{i18next.t(
"error:Please resolve the following issues before submitting"
)}
<ul>
{problems.map((problem, i) => {
if (problem === "Please sign out before sign up") {
return (
<li>
{i18next.t(`error:${this.state.message}`)} &nbsp;{" "}
<a href="#;" onClick={() => this.signOut()}>
{i18next.t("signout:Click to sign out")}
</a>
</li>
);
}
return <li>{i18next.t(`error:${problem}`)}</li>;
})}
</ul>
</div>
);
}
sendValidateCode() {
if (this.state.signupMethod === "sms") {
if (this.state.form.phone === "" || this.state.form.phone === undefined) {
this.setState({
message: "Please input your phone number",
});
return;
}
if (!/^\d+$/.test(this.state.form.phone)) {
this.setState({
message: "Please check your phone number",
});
return;
}
} else {
if (this.state.form.email === "" || this.state.form.email === undefined) {
this.setState({
message: "Please input your email",
});
return;
}
// just the simplest judgment to fit more situations.
if (!/\S+@\S+\.\S+/.test(this.state.form.email)) {
this.setState({
message: "Please check your email",
});
return;
}
}
let verifyType = 1,
information = this.state.form.phone;
if (this.state.signupMethod === "email") {
verifyType = 2;
information = this.state.form.email;
}
BasicBackend.getValidateCode(information, verifyType).then((res) => {
if (res?.status === "ok") {
this.setState(
{
validateCodeId: res?.data,
},
() => {
this.updateFormField("validateCodeId", this.state.validateCodeId);
}
);
} else {
this.setState({
message: res?.msg,
});
return;
}
});
if (!this.state.sendStatus) {
this.setState(
{
count: 60,
counting: true,
sendStatus: true,
showValidateCode: true,
},
() => {
this.countDown();
}
);
}
}
postSignup() {
if (this.state.form.areaCode === undefined) {
this.updateFormField("areaCode", Area_Code[0].value);
}
if (
this.state.form.username === "" ||
this.state.form.username === undefined
) {
this.setState({
message: "Please input username",
});
return;
}
if (
this.state.form.password === "" ||
this.state.form.password === undefined
) {
this.setState({
message: "Please input password",
});
return;
}
if (this.state.signupMethod === "sms") {
if (this.state.form.phone === "" || this.state.form.phone === undefined) {
this.setState({
message: "Please input your phone number",
});
return;
}
} else {
if (this.state.form.email === "" || this.state.form.email === undefined) {
this.setState({
message: "Please input your email",
});
return;
}
}
AccountBackend.signup(this.state.form).then((res) => {
if (res?.status === "ok") {
this.props.refreshAccount();
this.props.history.push("/");
} else {
this.setState({
message: res?.msg,
});
}
});
}
getIndexFromAreaCode(value) {
for (let i = 0; i < Area_Code.length; i++) {
if (Area_Code[i].value === value) {
return i;
}
}
return -1;
}
renderValidateCode() {
if (!this.state.showValidateCode) {
return null;
}
return (
<tr>
<td width="120" align="right">
{i18next.t("signup:Validate Code")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="validateCode"
maxLength="32"
onChange={(event) =>
this.updateFormField("validateCode", event.target.value)
}
autoComplete="off"
/>
<span className="negative"> *</span>
</td>
</tr>
);
}
render() {
if (
this.state.signupMethod === "sms" ||
this.state.signupMethod === "email"
) {
return (
<div className="box">
<div className="header">
<Link to="/">{Setting.getForumName()}</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
<Link to="/signup">Sign up</Link>{" "}
<span className="chevron">&nbsp;&nbsp;</span>{" "}
<Link to="/settings">
{this.state.signupMethod === "sms" ? "Phone" : "Email"}
</Link>
</div>
{this.renderProblem()}
<div className="inner">
<table cellPadding="5" cellSpacing="0" border="0" width="100%">
<tbody>
<tr>
<td width="120" align="right">
{i18next.t("signup:Username")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="username"
maxLength="20"
onChange={(event) =>
this.updateFormField("username", event.target.value)
}
autoComplete="off"
/>
<span className="negative"> *</span>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("signup:Password")}
</td>
<td width="auto" align="left">
<input
type="password"
className="sl"
name="password"
maxLength="20"
onChange={(event) =>
this.updateFormField("password", event.target.value)
}
autoComplete="off"
/>
<span className="negative"> *</span>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("signup:Email")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="email"
onChange={(event) =>
this.updateFormField("email", event.target.value)
}
autoComplete="off"
/>
{this.state.signupMethod === "email" ? (
<span>
<span className="negative"> * </span>
{this.state.sendStatus ? (
this.state.counting ? (
<span>
{i18next.t(
"signup:Send the verification code again in"
)}{" "}
{this.state.count} {i18next.t("signup:seconds")}
</span>
) : (
<a
href="#;"
onClick={() => this.sendValidateCode()}
>
{i18next.t("signup:Click to send validate code")}
</a>
)
) : (
<a href="#;" onClick={() => this.sendValidateCode()}>
{i18next.t("signup:Click to send validate code")}
</a>
)}
</span>
) : null}
</td>
</tr>
{this.state.signupMethod === "email"
? this.renderValidateCode()
: null}
<tr>
<td width="120" align="right">
{i18next.t("signup:Company")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="company"
onChange={(event) =>
this.updateFormField("company", event.target.value)
}
autoComplete="off"
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("signup:Company title")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="companyTitle"
maxLength="20"
onChange={(event) =>
this.updateFormField("companyTitle", event.target.value)
}
autoComplete="off"
/>
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("signup:Location")}
</td>
<td width="auto" align="left">
<input
type="text"
className="sl"
name="location"
maxLength="32"
onChange={(event) =>
this.updateFormField("location", event.target.value)
}
autoComplete="off"
/>
</td>
</tr>
<tr>
<td width="120" align="right" valign="top">
<div className="sep5"></div>
{i18next.t("signup:Area code")}
</td>
<td width="auto" align="left">
{this.state.signupMethod === "email" ? (
<Select2
value={this.getIndexFromAreaCode(
this.state.form.areaCode
)}
style={{
width: Setting.PcBrowser ? "300px" : "200px",
fontSize: "14px",
}}
data={Area_Code.map((code, i) => {
return { text: `${code.label}`, id: i };
})}
onSelect={(event) => {
const s = event.target.value;
if (s === null) {
return;
}
const index = parseInt(s);
const codeValue = Area_Code[index].value;
this.updateFormField("areaCode", codeValue);
}}
options={{
placeholder: i18next.t(
"signup:Please select a area code"
),
}}
/>
) : (
<span className="gray">{Area_Code[0].label}</span>
)}
</td>
</tr>
<tr>
<td width="120" align="right">
{i18next.t("signup:Phone")}
</td>
{this.state.signupMethod === "sms" ? (
<td width="auto" align="left">
<input
type="text"
className="sl"
name="location"
maxLength="11"
onChange={(event) =>
this.updateFormField("phone", event.target.value)
}
autoComplete="off"
/>
<span className="negative"> * </span>
{this.state.sendStatus ? (
this.state.counting ? (
<span>
{i18next.t(
"signup:Send the verification code again in"
)}{" "}
{this.state.count} {i18next.t("signup:seconds")}
</span>
) : (
<a href="#;" onClick={() => this.sendValidateCode()}>
{i18next.t("signup:Click to send validate code")}
</a>
)
) : (
<a href="#;" onClick={() => this.sendValidateCode()}>
{i18next.t("signup:Click to send validate code")}
</a>
)}
</td>
) : (
<td width="auto" align="left">
<input
type="text"
className="sl"
name="location"
maxLength="11"
onChange={(event) =>
this.updateFormField("phone", event.target.value)
}
autoComplete="off"
/>
</td>
)}
</tr>
{this.state.signupMethod === "sms"
? this.renderValidateCode()
: null}
<tr>
<td width="120" align="right"></td>
<td width="auto" align="left">
<input type="hidden" />
<input
type="submit"
className="super normal button"
value={i18next.t("signup:Signup")}
onClick={() => this.postSignup()}
/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
return (
<div className="box">
<Header item={i18next.t("member:Sign Up")} />
<div className="cell">
<div className="topic_content markdown_body">
<p
style={{ marginBlockStart: "1em", marginBlockEnd: "1em" }}
>{`${i18next.t(
"member:Welcome to"
)} ${Setting.getForumName()}${i18next.t(
"member:, this is the official forum for Casbin developers and users."
)}`}</p>
<p style={{ marginBlockStart: "1em", marginBlockEnd: "1em" }}>
{i18next.t(
"member:You can use the following ways to sign up as a new user."
)}
</p>
<p style={{ marginBlockStart: "1em", marginBlockEnd: "1em" }}>
{i18next.t(
"member:If you have previously signed up an account via Email, please click"
)}{" "}
<Link to="/signin">{i18next.t("member:here")}</Link>{" "}
{i18next.t("member:to sign in.")}
</p>
</div>
</div>
<div className="dock_area">
<div className="signup_methods">
<div
className="signup_method"
onClick={() => this.props.history.push("/signup/sms")}
>
<div className="signup_method_icon signup_method_sms"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with Mobile Phone")}
</div>
</div>
<div
className="signup_method"
onClick={() => this.props.history.push("/signup/email")}
>
<div className="signup_method_icon signup_method_email"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with Email")}
</div>
</div>
{Conf.QQClientId !== "" ? (
<div
className="signup_method"
onClick={() => Setting.getQQAuthCode("signup")}
>
<div className="signup_method_icon signup_method_qq"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with QQ")}
</div>
</div>
) : null}
{Conf.WechatClientId !== "" ? (
<div
className="signup_method"
onClick={() => Setting.getWeChatAuthCode("signup")}
>
<div className="signup_method_icon signup_method_wechat"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with WeChat")}
</div>
</div>
) : null}
{Conf.GoogleClientId !== "" ? (
<div
className="signup_method"
onClick={() => Setting.getGoogleAuthCode("signup")}
>
<div className="signup_method_icon signup_method_google"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with Google")}
</div>
</div>
) : null}
{Conf.GithubClientId !== "" ? (
<div
className="signup_method"
onClick={() => Setting.getGithubAuthCode("signup")}
>
<div className="signup_method_icon signup_method_github"></div>
<div className="signup_method_label" style={{ width: 230 }}>
{i18next.t("signup:Continue with Github")}
</div>
</div>
) : null}
</div>
</div>
</div>
);
}
}
export default withRouter(SignupBox);

View File

@ -13,10 +13,7 @@
// limitations under the License.
import React from "react";
import * as Setting from "../Setting";
import * as Conf from "../Conf";
import { withRouter, Link } from "react-router-dom";
import "./rightSignin.css";
import i18next from "i18next";
class RightSigninBox extends React.Component {
@ -28,66 +25,6 @@ class RightSigninBox extends React.Component {
}
render() {
if (window.location.pathname === "/signin") {
return (
<div className="box">
<div className="header">{i18next.t("bar:Other Sign In Methods")}</div>
{Conf.QQClientId !== "" ? (
<div className="cell" style={{ textAlign: "center" }}>
<div
className="signin_method"
onClick={() => Setting.getQQAuthCode("signup")}
>
<div className="signin_method_icon signin_method_qq"></div>
<div className="signin_method_label" style={{ width: 140 }}>
{i18next.t("signin:Sign in with QQ")}
</div>
</div>
</div>
) : null}
{Conf.WechatClientId !== "" ? (
<div className="cell" style={{ textAlign: "center" }}>
<div
className="signin_method"
onClick={() => Setting.getWeChatAuthCode("signup")}
>
<div className="signin_method_icon signin_method_wechat"></div>
<div className="signin_method_label" style={{ width: 140 }}>
{i18next.t("signin:Sign in with WeChat")}
</div>
</div>
</div>
) : null}
{Conf.GoogleClientId !== "" ? (
<div className="cell" style={{ textAlign: "center" }}>
<div
className="signin_method"
onClick={() => Setting.getGoogleAuthCode("signup")}
>
<div className="signin_method_icon signin_method_google"></div>
<div className="signin_method_label" style={{ width: 140 }}>
{i18next.t("signin:Sign in with Google")}
</div>
</div>
</div>
) : null}
{Conf.GithubClientId !== "" ? (
<div className="cell" style={{ textAlign: "center" }}>
<div
className="signin_method"
onClick={() => Setting.getGithubAuthCode("signup")}
>
<div className="signin_method_icon signin_method_github"></div>
<div className="signin_method_label" style={{ width: 140 }}>
{i18next.t("signin:Sign in with Github")}
</div>
</div>
</div>
) : null}
</div>
);
}
return (
<div className="box">
<div className="cell">

View File

@ -1,83 +0,0 @@
/* Copyright 2020 The casbin Authors. All Rights Reserved. */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
.signin_method_icon {
background-color: transparent;
display: inline-block;
width: 30px;
height: 30px;
}
.signin_method {
transition: box-shadow 0.4s ease, background-color 0.4s ease, color 0.4s ease;
text-decoration: none;
display: block;
margin: 1px auto;
padding: 10px;
background-color: #fff;
/* border-radius: 52px; */
min-width: 210px;
line-height: 100%;
display: flex;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
width: 191px;
/* height: 46px; */
font-size: 10px;
height: 30px;
align-items: center;
}
.signin_method:hover {
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.signin_method:active {
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.05);
background-color: #eeeeee;
color: #fff;
}
.signin_method_qq {
background-image: url("https://cdn.jsdelivr.net/gh/casbin/static/img/social_qq.png");
background-size: 30px 30px;
background-repeat: no-repeat;
}
.signin_method_wechat {
background-image: url("https://cdn.jsdelivr.net/gh/casbin/static/img/social_wechat.png");
background-size: 30px 30px;
background-repeat: no-repeat;
}
.signin_method_google {
background-image: url("https://cdn.jsdelivr.net/gh/casbin/static/img/social_google.png");
background-size: 30px 30px;
background-repeat: no-repeat;
}
.signin_method_github {
background-image: url("https://cdn.jsdelivr.net/gh/casbin/static/img/social_github.png");
background-size: 30px 30px;
background-repeat: no-repeat;
}
.signin_method_label {
font-size: 14px;
height: 32px;
line-height: 32px;
padding-left: 0.8em;
color: #757575;
text-align: center;
font-weight: 500;
}