Skip to content

Commit

Permalink
Merge branch 'main' into feature-api-cli-generic-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
helderbetiol committed Jan 4, 2024
2 parents 6844505 + a138326 commit 9fa6628
Show file tree
Hide file tree
Showing 28 changed files with 331 additions and 95 deletions.
104 changes: 104 additions & 0 deletions API/controllers/entityController.go
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,110 @@ func GetEntity(w http.ResponseWriter, r *http.Request) {
}
}

// swagger:operation GET /api/layers/{id}/objects Objects GetLayerObjects
// Gets the object of a given layer.
// Apply the layer filters to get children objects of a given root query param.
// ---
// security:
// - bearer: []
// produces:
// - application/json
// parameters:
// - name: id
// in: path
// description: 'ID of desired layer.'
// required: true
// type: string
// default: "layer_slug"
// - name: root
// in: query
// description: 'Mandatory, accepts IDs. The root object from where to apply the layer'
// required: true
// - name: recursive
// in: query
// description: 'Accepts true or false. If true, get objects
// from all levels beneath root. If false, get objects directly under root.'
// responses:
// '200':
// description: 'Found. A response body will be returned with
// a meaningful message.'
// '400':
// description: Bad request. An error message will be returned.
// '404':
// description: Not Found. An error message will be returned.

func GetLayerObjects(w http.ResponseWriter, r *http.Request) {
fmt.Println("******************************************************")
fmt.Println("FUNCTION CALL: GetLayerObjects ")
fmt.Println("******************************************************")
DispRequestMetaData(r)
var data map[string]interface{}
var id string
var canParse bool
var modelErr *u.Error

// Get user roles for permissions
user := getUserFromToken(w, r)
if user == nil {
return
}

// Get query params
var filters u.LayerObjsFilters
decoder.Decode(&filters, r.URL.Query())
if filters.Root == "" {
//error
w.WriteHeader(http.StatusBadRequest)
u.Respond(w, u.Message("Query param root is mandatory"))
return
}

if id, canParse = mux.Vars(r)["slug"]; canParse {
// Get layer
data, modelErr = models.GetObject(bson.M{"slug": id}, u.EntityToString(u.LAYER), u.RequestFilters{}, user.Roles)
if modelErr != nil {
u.RespondWithError(w, modelErr)
}

// Apply layer to get objects request
req := bson.M{}
for filterName, filterValue := range data["filters"].(map[string]interface{}) {
u.AddFilterToReq(req, filterName, filterValue.(string))
}
var searchId string
if filters.IsRecursive {
searchId = filters.Root + ".**.*"
} else {
searchId = filters.Root + ".*"
}
u.AddFilterToReq(req, "id", searchId)

// Get objects
matchingObjects := []map[string]interface{}{}
entities := u.GetEntitiesByNamespace(u.Any, searchId)
for _, entStr := range entities {
entData, err := models.GetManyObjects(entStr, req, u.RequestFilters{}, user.Roles)
if err != nil {
u.RespondWithError(w, err)
return
}
matchingObjects = append(matchingObjects, entData...)
}

// Respond
if r.Method == "OPTIONS" {
w.Header().Add("Content-Type", "application/json")
w.Header().Add("Allow", "GET, DELETE, OPTIONS, PATCH, PUT")
} else {
u.Respond(w, u.RespDataWrapper("successfully processed request", matchingObjects))
}
} else {
w.WriteHeader(http.StatusBadRequest)
u.Respond(w, u.Message("Error while parsing path parameters"))
return
}
}

// swagger:operation GET /api/{entity} Objects GetAllEntities
// Gets all present objects for specified entity (category).
// Returns JSON body with all specified objects of type.
Expand Down
4 changes: 2 additions & 2 deletions API/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ require (
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/stretchr/testify v1.8.4
github.com/vincent-petithory/dataurl v1.0.0
go.mongodb.org/mongo-driver v1.13.0
golang.org/x/crypto v0.15.0
go.mongodb.org/mongo-driver v1.13.1
golang.org/x/crypto v0.17.0
)

require (
Expand Down
9 changes: 5 additions & 4 deletions API/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gi
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.13.0 h1:67DgFFjYOCMWdtTEmKFpV3ffWlFnh+CYZ8ZS/tXWUfY=
go.mongodb.org/mongo-driver v1.13.0/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705 h1:ba9YlqfDGTTQ5aZ2fwOoQ1hf32QySyQkR6ODGDzHlnE=
golang.org/x/exp v0.0.0-20220321173239-a90fa8a75705/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
Expand Down Expand Up @@ -80,6 +80,7 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
4 changes: 4 additions & 0 deletions API/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ func Router(jwt func(next http.Handler) http.Handler) *mux.Router {
router.HandleFunc("/api/{entity}s/{id}",
controllers.GetEntity).Methods("GET", "HEAD", "OPTIONS")

//GET LAYER
router.HandleFunc("/api/layers/{slug}/objects",
controllers.GetLayerObjects).Methods("GET", "HEAD", "OPTIONS")

// GET ALL ENTITY
router.HandleFunc("/api/{entity}s",
controllers.GetAllEntities).Methods("HEAD", "GET")
Expand Down
50 changes: 50 additions & 0 deletions API/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,56 @@
}
}
},
"/api/layers/{id}/objects": {
"get": {
"security": [
{
"bearer": []
}
],
"description": "Apply the layer filters to get children objects of a given root query param.",
"produces": [
"application/json"
],
"tags": [
"Objects"
],
"summary": "Gets the object of a given layer.",
"operationId": "GetLayerObjects",
"parameters": [
{
"type": "string",
"default": "layer_slug",
"description": "ID of desired layer.",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Mandatory, accepts IDs. The root object from where to apply the layer",
"name": "root",
"in": "query",
"required": true
},
{
"description": "Accepts true or false. If true, get objects from all levels beneath root. If false, get objects directly under root.",
"name": "recursive",
"in": "query"
}
],
"responses": {
"200": {
"description": "Found. A response body will be returned with a meaningful message."
},
"400": {
"description": "Bad request. An error message will be returned."
},
"404": {
"description": "Not Found. An error message will be returned."
}
}
}
},
"/api/login": {
"post": {
"description": "Create a new JWT Key. This can also be used to verify credentials\nThe authorize and 'Try it out' buttons don't work",
Expand Down
58 changes: 34 additions & 24 deletions API/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/elliotchance/pie/v2"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)

var BuildHash string
Expand Down Expand Up @@ -76,6 +77,11 @@ type RequestFilters struct {
Id string `schema:"id"`
}

type LayerObjsFilters struct {
Root string `schema:"root"`
IsRecursive bool `schema:"recursive"`
}

type HierarchyFilters struct {
Namespace Namespace `schema:"namespace"`
StartDate string `schema:"startDate"`
Expand Down Expand Up @@ -174,35 +180,39 @@ func FilteredReqFromQueryParams(link *url.URL) bson.M {
for key := range queryValues {
if key != "fieldOnly" && key != "startDate" && key != "endDate" &&
key != "limit" && key != "namespace" {
var keyValue interface{}
keyValue = queryValues.Get(key)

if key == "parentId" {
regex := applyWildcards(keyValue.(string)) + `\.(` + NAME_REGEX + ")"
bsonMap["id"] = regexToMongoFilter(regex)
continue
} else if key == "tag" {
// tag is in tags list
bsonMap["tags"] = bson.M{"$eq": keyValue}
continue
} else if strings.Contains(keyValue.(string), "*") {
regex := applyWildcards(keyValue.(string))
keyValue = regexToMongoFilter(regex)
}

switch key {
case "id", "name", "category",
"description", "domain",
"createdDate", "lastUpdated", "slug":
bsonMap[key] = keyValue
default:
bsonMap["attributes."+key] = keyValue
}
keyValue := queryValues.Get(key)
AddFilterToReq(bsonMap, key, keyValue)
}
}
return bsonMap
}

func AddFilterToReq(bsonMap primitive.M, key string, value string) {
var keyValue interface{}
keyValue = value
if key == "parentId" {
regex := applyWildcards(keyValue.(string)) + `\.(` + NAME_REGEX + ")"
bsonMap["id"] = regexToMongoFilter(regex)
return
} else if key == "tag" {
// tag is in tags list
bsonMap["tags"] = bson.M{"$eq": keyValue}
return
} else if strings.Contains(keyValue.(string), "*") {
regex := applyWildcards(keyValue.(string))
keyValue = regexToMongoFilter(regex)
}

switch key {
case "id", "name", "category",
"description", "domain",
"createdDate", "lastUpdated", "slug":
bsonMap[key] = keyValue
default:
bsonMap["attributes."+key] = keyValue
}
}

func ErrTypeToStatusCode(errType ErrType) int {
switch errType {
case ErrForbidden:
Expand Down
2 changes: 1 addition & 1 deletion APP/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ENV TZ=Europe/Paris \

# Install dependencies
RUN apt-get update
RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback lib32stdc++6 python3
RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback python3
RUN apt-get clean

# Download Flutter SDK from Github repo
Expand Down
2 changes: 2 additions & 0 deletions APP/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ To quickly deploy a frontend and docker backend in SuperAdmin mode, just execute
.\launch.ps1
# Linux
./launch.sh
# MacOS
./launch.sh -m
```
For more options, check the documentation under `deploy/`.

Expand Down
2 changes: 1 addition & 1 deletion APP/lib/common/api_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ Future<Result<List<DockerContainer>, Exception>> fetchTenantDockerInfo(
print("API get Tenant Docker Info");
client ??= http.Client();
try {
Uri url = Uri.parse('$apiUrl/api/tenants/${tenantName.toLowerCase()}');
Uri url = Uri.parse('$apiUrl/api/tenants/${tenantName}');
final response = await client.get(url, headers: getHeader(token));
print(response.statusCode);
if (response.statusCode == 200) {
Expand Down
8 changes: 4 additions & 4 deletions APP/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,10 @@ packages:
dependency: "direct dev"
description:
name: mockito
sha256: "4b693867cee1853c9d1d7ecc1871f27f39b2ef2c13c0d8d8507dfe5bebd8aaf1"
sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917"
url: "https://pub.dev"
source: hosted
version: "5.4.3"
version: "5.4.4"
package_config:
dependency: transitive
description:
Expand Down Expand Up @@ -694,10 +694,10 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba
sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86
url: "https://pub.dev"
source: hosted
version: "6.2.1"
version: "6.2.2"
url_launcher_android:
dependency: transitive
description:
Expand Down
4 changes: 2 additions & 2 deletions APP/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ dependencies:
syncfusion_localizations: ^22.1.37
flutter_fancy_tree_view: ^1.4.1
http: ^1.1.0
url_launcher: ^6.2.1
url_launcher: ^6.2.2
csv: ^5.1.1
path_provider: ^2.0.14
universal_html: ^2.2.1
file_picker: ^5.2.10
flutter_dotenv: ^5.0.2

dev_dependencies:
mockito: ^5.4.3
mockito: ^5.4.4
build_runner: ^2.4.7
flutter_test:
sdk: flutter
Expand Down
9 changes: 8 additions & 1 deletion CLI/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,8 @@ func (n *createTagNode) execute() (interface{}, error) {
type createLayerNode struct {
slug node
applicability node
filterName string
filterValue node
}

func (n *createLayerNode) execute() (interface{}, error) {
Expand All @@ -1275,7 +1277,12 @@ func (n *createLayerNode) execute() (interface{}, error) {
return nil, err
}

return nil, cmd.C.CreateLayer(slug, applicability)
filterValue, err := nodeToString(n.filterValue, "filterValue")
if err != nil {
return nil, err
}

return nil, cmd.C.CreateLayer(slug, applicability, n.filterName, filterValue)
}

type createCorridorNode struct {
Expand Down
Loading

0 comments on commit 9fa6628

Please sign in to comment.