File: utils.go

package info (click to toggle)
golang-github-mendersoftware-go-lib-micro 0.0~git20211108.4e20429%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, experimental, forky, sid, trixie
  • size: 656 kB
  • sloc: makefile: 5
file content (114 lines) | stat: -rw-r--r-- 3,146 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2021 Northern.tech AS
//
//    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 store

import (
	"context"
	"strings"

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

	"github.com/mendersoftware/go-lib-micro/identity"
	mdoc "github.com/mendersoftware/go-lib-micro/mongo/doc"
	v1 "github.com/mendersoftware/go-lib-micro/store"
)

const FieldTenantID = "tenant_id"

// WithTenantID adds the tenant_id field to a bson document using the value extracted
// from the identity of the context
func WithTenantID(ctx context.Context, doc interface{}) bson.D {
	var (
		tenantID string
		res      bson.D
	)

	identity := identity.FromContext(ctx)
	if identity != nil {
		tenantID = identity.Tenant
	}
	tenantElem := bson.E{Key: FieldTenantID, Value: tenantID}

	switch v := doc.(type) {
	case map[string]interface{}:
		res = make(bson.D, 0, len(v)+1)
		for k, v := range v {
			res = append(res, bson.E{Key: k, Value: v})
		}
	case bson.M:
		res = make(bson.D, 0, len(v)+1)
		for k, v := range v {
			res = append(res, bson.E{Key: k, Value: v})
		}
	case bson.D:
		res = make(bson.D, len(v), len(v)+1)
		copy(res, v)

	case bson.Marshaler:
		b, err := v.MarshalBSON()
		if err != nil {
			return nil
		}
		err = bson.Unmarshal(b, &res)
		if err != nil {
			return nil
		}
	default:
		return mdoc.DocumentFromStruct(v, tenantElem)
	}
	res = append(res, tenantElem)

	return res
}

// ArrayWithTenantID adds the tenant_id field to an array of bson documents
// using the value extracted from the identity of the context
func ArrayWithTenantID(ctx context.Context, doc bson.A) bson.A {
	res := bson.A{}
	for _, item := range doc {
		res = append(res, WithTenantID(ctx, item))
	}
	return res
}

// DbFromContext generates database name using tenant field from identity extracted
// from context and original database name
func DbFromContext(ctx context.Context, origDbName string) string {
	return origDbName
}

// IsTenantDb returns a function of `TenantDbMatchFunc` that can be used for
// checking if database has a tenant DB name format
func IsTenantDb(baseDb string) v1.TenantDbMatchFunc {
	prefix := baseDb + "-"
	return func(name string) bool {
		return strings.HasPrefix(name, prefix)
	}
}

// TenantFromDbName attempts to extract tenant ID from provided tenant DB name.
// Returns extracted tenant ID or an empty string.
func TenantFromDbName(dbName string, baseDb string) string {
	noBase := strings.TrimPrefix(dbName, baseDb+"-")
	if noBase == dbName {
		return ""
	}
	return noBase
}

// DbNameForTenant composes tenant's db name.
func DbNameForTenant(tenantId string, baseDb string) string {
	return baseDb
}