Skip to content

Commit

Permalink
update filter options
Browse files Browse the repository at this point in the history
  • Loading branch information
morphy2k committed Jan 12, 2024
1 parent 1a3d188 commit 742598d
Show file tree
Hide file tree
Showing 9 changed files with 291 additions and 102 deletions.
6 changes: 6 additions & 0 deletions controller/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ func isAlnumBlankPunct(s string) bool {
return !regexNonAlnumBlankPunct.MatchString(s)
}

var regexNotAllowedQueryChars = regexp.MustCompile(`[^[:alnum:][:blank:]!#%&'()*+,\-./:;?_~]`)

func isAllowedQueryChars(s string) bool {
return !regexNotAllowedQueryChars.MatchString(s)
}

func handleError(err error, w http.ResponseWriter) {
var res *Status

Expand Down
148 changes: 105 additions & 43 deletions controller/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,87 +134,149 @@ Loop:
}

if result == nil {
filter := model.Filter{}
var filter model.DocumentFilter

switch kind {
case item.KindArmor:
err = filter.AddString("type", r.URL.Query().Get("type"))
if err != nil {
break
armorFilter := &item.ArmorFilter{}

if v := r.URL.Query().Get("type"); v != "" {
if !isAllowedQueryChars(v) {
break
}
armorFilter.Type = &v
}

err = filter.AddInt("armor.class", r.URL.Query().Get("armor.class"))
if err != nil {
break
if v := r.URL.Query().Get("armor.class"); v != "" {
if v, err := strconv.ParseInt(v, 10, 64); err == nil {
armorFilter.ArmorClass = &v
} else {
break
}
}

err = filter.AddString("armor.material.name", r.URL.Query().Get("armor.material.name"))
if err != nil {
break
if v := r.URL.Query().Get("armor.material.name"); v != "" {
if !isAllowedQueryChars(v) {
break
}
armorFilter.MaterialName = &v
}

filter = armorFilter
case item.KindFirearm:
err = filter.AddString("manufacturer", r.URL.Query().Get("manufacturer"))
if err != nil {
break
firearmFilter := &item.FirearmFilter{}

if v := r.URL.Query().Get("type"); v != "" {
if !isAllowedQueryChars(v) {
break
}
firearmFilter.Type = &v
}

err = filter.AddString("type", r.URL.Query().Get("type"))
if err != nil {
break
if v := r.URL.Query().Get("class"); v != "" {
if !isAllowedQueryChars(v) {
break
}
firearmFilter.Class = &v
}

err = filter.AddString("class", r.URL.Query().Get("class"))
if err != nil {
break
if v := r.URL.Query().Get("caliber"); v != "" {
if !isAllowedQueryChars(v) {
break
}
firearmFilter.Caliber = &v
}

err = filter.AddString("caliber", r.URL.Query().Get("caliber"))
if err != nil {
break
if v := r.URL.Query().Get("manufacturer"); v != "" {
if !isAllowedQueryChars(v) {
break
}
firearmFilter.Manufacturer = &v
}

filter = firearmFilter
case item.KindTacticalrig:
if v := r.URL.Query().Get("armored"); v != "" {
tacticalrigFilter := &item.TacticalRigFilter{}

if v := r.URL.Query().Get("isPlateCarrier"); v != "" {
if v, err := strconv.ParseBool(v); err == nil {
filter["armor"] = bson.D{{Key: "$exists", Value: v}}
tacticalrigFilter.IsPlateCarrier = &v
} else {
break
}
}

err = filter.AddInt("armor.class", r.URL.Query().Get("armor.class"))
if err != nil {
break
if v := r.URL.Query().Get("isArmored"); v != "" {
if v, err := strconv.ParseBool(v); err == nil {
tacticalrigFilter.IsArmored = &v
} else {
break
}
}

err = filter.AddString("armor.material.name", r.URL.Query().Get("armor.material.name"))
if err != nil {
break
if v := r.URL.Query().Get("armor.class"); v != "" {
if v, err := strconv.ParseInt(v, 10, 64); err == nil {
tacticalrigFilter.ArmorClass = &v
} else {
break
}
}

if v := r.URL.Query().Get("armor.material"); v != "" {
if !isAllowedQueryChars(v) {
break
}
tacticalrigFilter.ArmorMaterial = &v
}

filter = tacticalrigFilter
case item.KindAmmunition:
err = filter.AddString("type", r.URL.Query().Get("type"))
if err != nil {
break
ammunitionFilter := &item.AmmunitionFilter{}

if v := r.URL.Query().Get("type"); v != "" {
if !isAllowedQueryChars(v) {
break
}
ammunitionFilter.Type = &v
}

err = filter.AddString("caliber", r.URL.Query().Get("caliber"))
if err != nil {
break
if v := r.URL.Query().Get("caliber"); v != "" {
if !isAllowedQueryChars(v) {
break
}
ammunitionFilter.Caliber = &v
}

filter = ammunitionFilter
case item.KindMagazine:
err = filter.AddString("caliber", r.URL.Query().Get("caliber"))
if err != nil {
break
magazineFilter := &item.MagazineFilter{}

if v := r.URL.Query().Get("caliber"); v != "" {
if !isAllowedQueryChars(v) {
break
}
magazineFilter.Caliber = &v
}

filter = magazineFilter
case item.KindMedical, item.KindFood, item.KindGrenade, item.KindClothing, item.KindModificationMuzzle, item.KindModificationDevice, item.KindModificationSight, item.KindModificationSightSpecial, item.KindModificationGoggles:
err = filter.AddString("type", r.URL.Query().Get("type"))
if err != nil {
break
customFilter := bson.D{}

if v := r.URL.Query().Get("type"); v != "" {
if !isAllowedQueryChars(v) {
break
}
customFilter = append(customFilter, bson.E{Key: "type", Value: v})
}

filter = &model.CustomFilter{D: customFilter}
}
if err != nil {
StatusBadRequest(fmt.Sprintf("Query string error: %s", err)).Render(w)
return
}

result, err = item.GetAll(filter, kind, opts)
result, err = item.GetAll(filter.Filter(), kind, opts)
if err != nil {
handleError(err, w)
return
Expand Down
8 changes: 5 additions & 3 deletions model/item/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,11 @@ func getManyByFilter(filter interface{}, k Kind, opts *Options) (*model.Result,
}

// GetAll returns a result based on filters
func GetAll(filter map[string]interface{}, k Kind, opts *Options) (*model.Result, error) {
filter["_kind"] = k
return getManyByFilter(filter, k, opts)
func GetAll(filter bson.D, k Kind, opts *Options) (*model.Result, error) {
f := bson.D{{Key: "_kind", Value: k}}
f = append(f, filter...)

return getManyByFilter(f, k, opts)
}

// GetByIDs returns a result by given IDs
Expand Down
27 changes: 27 additions & 0 deletions model/item/kind_ammunition.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package item

import "go.mongodb.org/mongo-driver/bson"

const (
// KindAmmunition represents the kind of Ammunition
KindAmmunition Kind = "ammunition"
Expand Down Expand Up @@ -62,3 +64,28 @@ type AmmoGrenadeProperties struct {
MinRadius float64 `json:"minRadius" bson:"minRadius"`
MaxRadius float64 `json:"maxRadius" bson:"maxRadius"`
}

// AmmunitionFilter describes the filters used for filtering Ammunition
type AmmunitionFilter struct {
Caliber *string
Type *string
}

// Filter implements the DocumentFilter interface
func (f *AmmunitionFilter) Filter() bson.D {
filters := []bson.M{}

if f.Caliber != nil {
filters = append(filters, bson.M{"caliber": *f.Caliber})
}

if f.Type != nil {
filters = append(filters, bson.M{"type": *f.Type})
}

if len(filters) == 0 {
return bson.D{}
}

return bson.D{{Key: "$and", Value: filters}}
}
38 changes: 38 additions & 0 deletions model/item/kind_armor.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package item

import "go.mongodb.org/mongo-driver/bson"

const (
// KindArmor represents the kind of Armor
KindArmor Kind = "armor"
Expand Down Expand Up @@ -39,3 +41,39 @@ type ArmorMaterial struct {
Name string `json:"name" bson:"name"`
Destructibility float64 `json:"destructibility" bson:"destructibility"`
}

// ArmorFilter describes the filters used for filtering Armor
type ArmorFilter struct {
Type *string
ArmorClass *int64
MaterialName *string
}

// Filter implements the DocumentFilter interface
func (f *ArmorFilter) Filter() bson.D {
filters := []bson.M{}

if f.Type != nil {
filters = append(filters, bson.M{"type": *f.Type})
}

if f.ArmorClass != nil {
filters = append(filters, bson.M{"$or": []bson.M{
{"armor.class": *f.ArmorClass},
{"components": bson.M{"$elemMatch": bson.M{"class": *f.ArmorClass}}},
}})
}

if f.MaterialName != nil {
filters = append(filters, bson.M{"$or": []bson.M{
{"armor.material.name": *f.MaterialName},
{"components": bson.M{"$elemMatch": bson.M{"material.name": *f.MaterialName}}},
}})
}

if len(filters) == 0 {
return bson.D{}
}

return bson.D{{Key: "$and", Value: filters}}
}
37 changes: 37 additions & 0 deletions model/item/kind_firearm.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package item

import "go.mongodb.org/mongo-driver/bson"

const (
// KindFirearm represents the kind of Firearm
KindFirearm Kind = "firearm"
Expand Down Expand Up @@ -34,3 +36,38 @@ type Firearm struct {
CenterOfImpact float64 `json:"centerOfImpact" bson:"centerOfImpact"`
Slots Slots `json:"slots" bson:"slots"`
}

// FirearmFilter describes the filters used for filtering Firearm
type FirearmFilter struct {
Manufacturer *string
Type *string
Class *string
Caliber *string
}

// Filter implements the DocumentFilter interface
func (f *FirearmFilter) Filter() bson.D {
filters := []bson.M{}

if f.Manufacturer != nil {
filters = append(filters, bson.M{"manufacturer": *f.Manufacturer})
}

if f.Type != nil {
filters = append(filters, bson.M{"type": *f.Type})
}

if f.Class != nil {
filters = append(filters, bson.M{"class": *f.Class})
}

if f.Caliber != nil {
filters = append(filters, bson.M{"caliber": *f.Caliber})
}

if len(filters) == 0 {
return bson.D{}
}

return bson.D{{Key: "$and", Value: filters}}
}
22 changes: 22 additions & 0 deletions model/item/kind_magazine.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package item

import "go.mongodb.org/mongo-driver/bson"

const (
// KindMagazine represents the kind of Magazine
KindMagazine Kind = "magazine"
Expand All @@ -25,3 +27,23 @@ type MagazineModifier struct {
CheckTime float64 `json:"checkTime" bson:"checkTime"`
LoadUnload float64 `json:"loadUnload" bson:"loadUnload"`
}

// MagazineFilter describes the filters used for filtering Magazine
type MagazineFilter struct {
Caliber *string
}

// Filter implements the DocumentFilter interface
func (f *MagazineFilter) Filter() bson.D {
filters := []bson.M{}

if f.Caliber != nil {
filters = append(filters, bson.M{"caliber": *f.Caliber})
}

if len(filters) == 0 {
return bson.D{}
}

return bson.D{{Key: "$and", Value: filters}}
}
Loading

0 comments on commit 742598d

Please sign in to comment.