filters.go 2.0 KB
package filter

import (
	"strings"

	"github.com/globalsign/mgo/bson"
	"github.com/tal-tech/go-stash/stash/config"
)

const (
	filterDrop         = "drop"
	filterRemoveFields = "remove_field"
	opAnd              = "and"
	opOr               = "or"
	typeContains       = "contains"
	typeMatch          = "match"
)

type FilterFunc func(map[string]interface{}) map[string]interface{}

func CreateFilters(c config.Config) []FilterFunc {
	var filters []FilterFunc

	for _, f := range c.Filters {
		switch f.Action {
		case filterDrop:
			filters = append(filters, DropFilter(f.Conditions))
		case filterRemoveFields:
			filters = append(filters, RemoveFieldFilter(f.Fields))
		}
	}

	return filters
}

func DropFilter(conds []config.Condition) FilterFunc {
	return func(m map[string]interface{}) map[string]interface{} {
		var qualify bool
		for _, cond := range conds {
			var qualifyOnce bool
			switch cond.Type {
			case typeMatch:
				qualifyOnce = cond.Value == m[cond.Key]
			case typeContains:
				if val, ok := m[cond.Key].(string); ok {
					qualifyOnce = strings.Contains(val, cond.Value)
				}
			}

			switch cond.Op {
			case opAnd:
				if !qualifyOnce {
					return m
				} else {
					qualify = true
				}
			case opOr:
				if qualifyOnce {
					qualify = true
				}
			}
		}

		if qualify {
			return nil
		} else {
			return m
		}
	}
}

func RemoveFieldFilter(fields []string) FilterFunc {
	return func(m map[string]interface{}) map[string]interface{} {
		for _, field := range fields {
			delete(m, field)
		}
		return m
	}
}

func AddUriFieldFilter(inField, outFirld string) FilterFunc {
	return func(m map[string]interface{}) map[string]interface{} {
		if val, ok := m[inField].(string); ok {
			var datas []string
			idx := strings.Index(val, "?")
			if idx < 0 {
				datas = strings.Split(val, "/")
			} else {
				datas = strings.Split(val[:idx], "/")
			}

			for i, data := range datas {
				if bson.IsObjectIdHex(data) {
					datas[i] = "*"
				}
			}

			m[outFirld] = strings.Join(datas, "/")
		}

		return m
	}
}