mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
339 lines
7.7 KiB
Go
339 lines
7.7 KiB
Go
// Copyright 2021 The Casdoor 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 object
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/beego/beego/context"
|
|
"github.com/casdoor/casdoor/conf"
|
|
"github.com/casdoor/casdoor/util"
|
|
"github.com/casvisor/casvisor-go-sdk/casvisorsdk"
|
|
)
|
|
|
|
var (
|
|
logPostOnly bool
|
|
passwordRegex *regexp.Regexp
|
|
)
|
|
|
|
func init() {
|
|
logPostOnly = conf.GetConfigBool("logPostOnly")
|
|
passwordRegex = regexp.MustCompile("\"password\":\"([^\"]*?)\"")
|
|
}
|
|
|
|
type Record struct {
|
|
casvisorsdk.Record
|
|
}
|
|
|
|
type Response struct {
|
|
Status string `json:"status"`
|
|
Msg string `json:"msg"`
|
|
}
|
|
|
|
func maskPassword(recordString string) string {
|
|
return passwordRegex.ReplaceAllString(recordString, "\"password\":\"***\"")
|
|
}
|
|
|
|
func NewRecord(ctx *context.Context) (*casvisorsdk.Record, error) {
|
|
clientIp := strings.Replace(util.GetClientIpFromRequest(ctx.Request), ": ", "", -1)
|
|
action := strings.Replace(ctx.Request.URL.Path, "/api/", "", -1)
|
|
requestUri := util.FilterQuery(ctx.Request.RequestURI, []string{"accessToken"})
|
|
if len(requestUri) > 1000 {
|
|
requestUri = requestUri[0:1000]
|
|
}
|
|
|
|
object := ""
|
|
if ctx.Input.RequestBody != nil && len(ctx.Input.RequestBody) != 0 {
|
|
object = string(ctx.Input.RequestBody)
|
|
object = maskPassword(object)
|
|
}
|
|
|
|
respBytes, err := json.Marshal(ctx.Input.Data()["json"])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var resp Response
|
|
err = json.Unmarshal(respBytes, &resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
language := ctx.Request.Header.Get("Accept-Language")
|
|
if len(language) > 2 {
|
|
language = language[0:2]
|
|
}
|
|
languageCode := conf.GetLanguage(language)
|
|
|
|
record := casvisorsdk.Record{
|
|
Name: util.GenerateId(),
|
|
CreatedTime: util.GetCurrentTime(),
|
|
ClientIp: clientIp,
|
|
User: "",
|
|
Method: ctx.Request.Method,
|
|
RequestUri: requestUri,
|
|
Action: action,
|
|
Language: languageCode,
|
|
Object: object,
|
|
StatusCode: 200,
|
|
Response: fmt.Sprintf("{status:\"%s\", msg:\"%s\"}", resp.Status, resp.Msg),
|
|
IsTriggered: false,
|
|
}
|
|
return &record, nil
|
|
}
|
|
|
|
func addRecord(record *casvisorsdk.Record) (int64, error) {
|
|
affected, err := ormer.Engine.Insert(record)
|
|
return affected, err
|
|
}
|
|
|
|
func AddRecord(record *casvisorsdk.Record) bool {
|
|
if logPostOnly {
|
|
if record.Method == "GET" {
|
|
return false
|
|
}
|
|
}
|
|
|
|
if record.Organization == "app" {
|
|
return false
|
|
}
|
|
|
|
record.Owner = record.Organization
|
|
record.Object = maskPassword(record.Object)
|
|
|
|
errWebhook := SendWebhooks(record)
|
|
if errWebhook == nil {
|
|
record.IsTriggered = true
|
|
} else {
|
|
fmt.Println(errWebhook)
|
|
}
|
|
|
|
if casvisorsdk.GetClient() == nil {
|
|
affected, err := addRecord(record)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return affected != 0
|
|
}
|
|
|
|
affected, err := casvisorsdk.AddRecord(record)
|
|
if err != nil {
|
|
fmt.Printf("AddRecord() error: %s", err.Error())
|
|
}
|
|
|
|
return affected
|
|
}
|
|
|
|
func GetRecordCount(field, value string, filterRecord *casvisorsdk.Record) (int64, error) {
|
|
session := GetSession("", -1, -1, field, value, "", "")
|
|
return session.Count(filterRecord)
|
|
}
|
|
|
|
func GetRecords() ([]*casvisorsdk.Record, error) {
|
|
records := []*casvisorsdk.Record{}
|
|
err := ormer.Engine.Desc("id").Find(&records)
|
|
if err != nil {
|
|
return records, err
|
|
}
|
|
|
|
return records, nil
|
|
}
|
|
|
|
func GetPaginationRecords(offset, limit int, field, value, sortField, sortOrder string, filterRecord *casvisorsdk.Record) ([]*casvisorsdk.Record, error) {
|
|
records := []*casvisorsdk.Record{}
|
|
|
|
if sortField == "" || sortOrder == "" {
|
|
sortField = "id"
|
|
sortOrder = "descend"
|
|
}
|
|
|
|
session := GetSession("", offset, limit, field, value, sortField, sortOrder)
|
|
err := session.Find(&records, filterRecord)
|
|
if err != nil {
|
|
return records, err
|
|
}
|
|
|
|
return records, nil
|
|
}
|
|
|
|
func GetRecordsByField(record *casvisorsdk.Record) ([]*casvisorsdk.Record, error) {
|
|
records := []*casvisorsdk.Record{}
|
|
err := ormer.Engine.Find(&records, record)
|
|
if err != nil {
|
|
return records, err
|
|
}
|
|
|
|
return records, nil
|
|
}
|
|
|
|
func CopyRecord(record *casvisorsdk.Record) *casvisorsdk.Record {
|
|
res := &casvisorsdk.Record{
|
|
Owner: record.Owner,
|
|
Name: record.Name,
|
|
CreatedTime: record.CreatedTime,
|
|
Organization: record.Organization,
|
|
ClientIp: record.ClientIp,
|
|
User: record.User,
|
|
Method: record.Method,
|
|
RequestUri: record.RequestUri,
|
|
Action: record.Action,
|
|
Language: record.Language,
|
|
Object: record.Object,
|
|
Response: record.Response,
|
|
IsTriggered: record.IsTriggered,
|
|
}
|
|
return res
|
|
}
|
|
|
|
func getFilteredWebhooks(webhooks []*Webhook, organization string, action string) []*Webhook {
|
|
res := []*Webhook{}
|
|
for _, webhook := range webhooks {
|
|
if !webhook.IsEnabled {
|
|
continue
|
|
}
|
|
|
|
if webhook.SingleOrgOnly {
|
|
if webhook.Organization != organization {
|
|
continue
|
|
}
|
|
}
|
|
|
|
matched := false
|
|
for _, event := range webhook.Events {
|
|
if action == event {
|
|
matched = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if matched {
|
|
res = append(res, webhook)
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
func addWebhookRecord(webhook *Webhook, record *casvisorsdk.Record, statusCode int, respBody string, sendError error) error {
|
|
if statusCode == 200 {
|
|
return nil
|
|
}
|
|
|
|
if len(respBody) > 300 {
|
|
respBody = respBody[0:300]
|
|
}
|
|
|
|
webhookRecord := &casvisorsdk.Record{
|
|
Owner: record.Owner,
|
|
Name: util.GenerateId(),
|
|
CreatedTime: util.GetCurrentTime(),
|
|
Organization: record.Organization,
|
|
User: record.User,
|
|
|
|
Method: webhook.Method,
|
|
Action: "send-webhook",
|
|
RequestUri: webhook.Url,
|
|
StatusCode: statusCode,
|
|
Response: respBody,
|
|
Language: record.Language,
|
|
IsTriggered: false,
|
|
}
|
|
|
|
if sendError != nil {
|
|
webhookRecord.Response = sendError.Error()
|
|
}
|
|
|
|
_, err := addRecord(webhookRecord)
|
|
|
|
return err
|
|
}
|
|
|
|
func filterRecordObject(object string, objectFields []string) string {
|
|
var rawObject map[string]interface{}
|
|
_ = json.Unmarshal([]byte(object), &rawObject)
|
|
|
|
if rawObject == nil {
|
|
return object
|
|
}
|
|
|
|
filteredObject := make(map[string]interface{})
|
|
|
|
for _, field := range objectFields {
|
|
fieldValue, ok := rawObject[field]
|
|
if !ok {
|
|
continue
|
|
}
|
|
filteredObject[field] = fieldValue
|
|
}
|
|
|
|
return util.StructToJson(filteredObject)
|
|
}
|
|
|
|
func SendWebhooks(record *casvisorsdk.Record) error {
|
|
webhooks, err := getWebhooksByOrganization("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
errs := []error{}
|
|
webhooks = getFilteredWebhooks(webhooks, record.Organization, record.Action)
|
|
|
|
record2 := *record
|
|
for _, webhook := range webhooks {
|
|
|
|
if len(webhook.ObjectFields) != 0 && webhook.ObjectFields[0] != "All" {
|
|
record2.Object = filterRecordObject(record.Object, webhook.ObjectFields)
|
|
}
|
|
|
|
var user *User
|
|
if webhook.IsUserExtended {
|
|
user, err = getUser(record.Organization, record.User)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
continue
|
|
}
|
|
|
|
user, err = GetMaskedUser(user, false, err)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
statusCode, respBody, err := sendWebhook(webhook, &record2, user)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
|
|
err = addWebhookRecord(webhook, &record2, statusCode, respBody, err)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
|
|
}
|
|
|
|
if len(errs) > 0 {
|
|
errStrings := []string{}
|
|
for _, err := range errs {
|
|
errStrings = append(errStrings, err.Error())
|
|
}
|
|
return fmt.Errorf(strings.Join(errStrings, " | "))
|
|
}
|
|
return nil
|
|
}
|