Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8f2b64e
fix gecko project creation so that gecko project server config is not…
matthewpeterkort Jun 9, 2026
f178e3d
fix gecko github disconnect logic
matthewpeterkort Jun 9, 2026
d661ca4
beef up security for fence endpoint
matthewpeterkort Jun 10, 2026
e53fe46
patch auth
matthewpeterkort Jun 10, 2026
00fa23f
fix an issue where git org/repo were not persisted in gecko project s…
matthewpeterkort Jun 10, 2026
3d7be06
add support for edit, add, delete connnections in github connection w…
matthewpeterkort Jun 10, 2026
bc71828
add presentation route
matthewpeterkort Jun 14, 2026
71c27ac
update presentation route to not sanitize html
matthewpeterkort Jun 14, 2026
242411e
patch gecko to have fallback authentication link be repo scoped so as…
matthewpeterkort Jun 16, 2026
b2d1038
optimize git endpoints
matthewpeterkort Jun 25, 2026
e65d7b2
patch an issue related to directories with spaces in their name
matthewpeterkort Jun 26, 2026
1f9bc46
fix up audit methods in gecko
matthewpeterkort Jul 1, 2026
af56e95
update analytics
matthewpeterkort Jul 2, 2026
97bdffb
fix LIST operation in gecko audit
matthewpeterkort Jul 2, 2026
9ebf621
upgrade audit analytics
matthewpeterkort Jul 2, 2026
12ca2d5
make backend support all error methods
matthewpeterkort Jul 3, 2026
fb1fce1
fix gecko audit fix wiring to match audit outputs
matthewpeterkort Jul 3, 2026
eab30ef
improve gecko storage directory path serving
matthewpeterkort Jul 4, 2026
863b11b
update funcs
matthewpeterkort Jul 4, 2026
db72864
cleanup api to be faster
matthewpeterkort Jul 4, 2026
90485af
optimize gecko routes in audit
matthewpeterkort Jul 7, 2026
aac2c29
fix false positives issues in gecko related to innaccurate bucket can…
matthewpeterkort Jul 7, 2026
9d95340
fix bugs
matthewpeterkort Jul 7, 2026
3049065
remove false positvies
matthewpeterkort Jul 8, 2026
18ed0c9
remove false positives, update apply route
matthewpeterkort Jul 8, 2026
97e425f
fix build errs
matthewpeterkort Jul 8, 2026
c452d06
re-enable http2
matthewpeterkort Jul 8, 2026
0f34f55
support redis caching for audits
matthewpeterkort Jul 8, 2026
332ee47
standardize path normalization in gecko audit route
matthewpeterkort Jul 8, 2026
6d15a57
remove false positives
matthewpeterkort Jul 9, 2026
aec3f3c
refactor audit to be better
matthewpeterkort Jul 9, 2026
3351caf
remove deadcode, fix false positive issue
matthewpeterkort Jul 10, 2026
2dc89a2
fix timeout issues related to performance of storage/folder?limit=100…
matthewpeterkort Jul 10, 2026
8f5281c
add support for viewing bucket only files
matthewpeterkort Jul 10, 2026
9f99a7e
add cache for successful syfon bucket LIST traversals
matthewpeterkort Jul 10, 2026
33f48fb
fix tests
matthewpeterkort Jul 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions config/presentationConfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package config

import "fmt"

type PresentationConfig struct {
PresentationConfig string `json:"presentationConfig"`
}

func (p PresentationConfig) IsZero() bool {
return p.PresentationConfig == ""
}

func (p *PresentationConfig) Validate() error {
if p == nil {
return fmt.Errorf("presentation config is required")
}
return nil
}
28 changes: 28 additions & 0 deletions config/presentationConfig_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import "testing"

func TestPresentationConfigValidateAllowsRawHTML(t *testing.T) {
cfg := &PresentationConfig{
PresentationConfig: `<div onclick="alert(1)"><script>alert(1)</script><a href="javascript:alert(1)" target="_blank">link</a><p>Hello</p></div>`,
}

if err := cfg.Validate(); err != nil {
t.Fatalf("validate failed: %v", err)
}

if cfg.PresentationConfig != `<div onclick="alert(1)"><script>alert(1)</script><a href="javascript:alert(1)" target="_blank">link</a><p>Hello</p></div>` {
t.Fatalf("unexpected raw HTML: %q", cfg.PresentationConfig)
}
}

func TestPresentationConfigValidateAllowsEmptyHTML(t *testing.T) {
cfg := &PresentationConfig{}

if err := cfg.Validate(); err != nil {
t.Fatalf("validate failed: %v", err)
}
if cfg.PresentationConfig != "" {
t.Fatalf("expected empty presentationConfig, got %q", cfg.PresentationConfig)
}
}
203 changes: 182 additions & 21 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,56 +215,213 @@ const docTemplate = `{
}
}
},
"/dir/{projectId}": {
"/git/projects/{orgTitle}/{projectTitle}/presentationConfig": {
"get": {
"description": "Retrieve directory details for the given project ID and Directory path",
"description": "Retrieve the raw presentation HTML configured for a project. Returns empty content when no presentation has been configured.",
"produces": [
"application/json"
],
"tags": [
"Directory"
"Git"
],
"summary": "Retrieve directory information for a project",
"summary": "Get project presentation HTML",
"parameters": [
{
"type": "string",
"description": "Project ID (format: program-project)",
"name": "projectId",
"description": "Organization title",
"name": "orgTitle",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Directory Path (e.g., /data/my-dir)",
"name": "directory_path",
"in": "query",
"description": "Project title",
"name": "projectTitle",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Directory information",
"description": "Presentation configuration",
"schema": {
"type": "object",
"additionalProperties": true
"$ref": "#/definitions/config.PresentationConfig"
}
},
"401": {
"description": "Missing authorization",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"404": {
"description": "Project not found",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"500": {
"description": "Server error",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
}
}
},
"post": {
"description": "Persist raw presentation HTML for a project.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Git"
],
"summary": "Create project presentation HTML",
"parameters": [
{
"type": "string",
"description": "Organization title",
"name": "orgTitle",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Project title",
"name": "projectTitle",
"in": "path",
"required": true
},
{
"description": "Presentation HTML payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/config.PresentationConfig"
}
}
],
"responses": {
"200": {
"description": "Persisted presentation configuration",
"schema": {
"$ref": "#/definitions/config.PresentationConfig"
}
},
"400": {
"description": "Invalid request body or Directory path",
"description": "Invalid request body",
"schema": {
"$ref": "#/definitions/gecko.ErrorResponse"
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"401": {
"description": "Missing authorization",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"403": {
"description": "User is not allowed on any resource path",
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/gecko.ErrorResponse"
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"404": {
"description": "Project not found",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"500": {
"description": "Server error",
"schema": {
"$ref": "#/definitions/gecko.ErrorResponse"
"$ref": "#/definitions/httputil.ErrorResponse"
}
}
}
},
"put": {
"description": "Persist raw presentation HTML for a project.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Git"
],
"summary": "Update project presentation HTML",
"parameters": [
{
"type": "string",
"description": "Organization title",
"name": "orgTitle",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Project title",
"name": "projectTitle",
"in": "path",
"required": true
},
{
"description": "Presentation HTML payload",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/config.PresentationConfig"
}
}
],
"responses": {
"200": {
"description": "Persisted presentation configuration",
"schema": {
"$ref": "#/definitions/config.PresentationConfig"
}
},
"400": {
"description": "Invalid request body",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"401": {
"description": "Missing authorization",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"404": {
"description": "Project not found",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
},
"500": {
"description": "Server error",
"schema": {
"$ref": "#/definitions/httputil.ErrorResponse"
}
}
}
Expand Down Expand Up @@ -1043,6 +1200,14 @@ const docTemplate = `{
}
}
},
"config.PresentationConfig": {
"type": "object",
"properties": {
"presentationConfig": {
"type": "string"
}
}
},
"config.ConfigItem": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1728,7 +1893,3 @@ var SwaggerInfo = &swag.Spec{
LeftDelim: "{{",
RightDelim: "}}",
}

func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
Loading
Loading