Compare commits
merge into: FabianVowie:main
FabianVowie:feature/add-authorization
FabianVowie:feature/add-commit-hash-to-index-metadata
FabianVowie:feature/add-executable-steps
FabianVowie:feature/add-get-files-endpoints
FabianVowie:feature/add-github-ci
FabianVowie:feature/add-http-image-upload
FabianVowie:feature/add-image-processing
FabianVowie:feature/add-logging
FabianVowie:feature/add-metadata-endpoint
FabianVowie:feature/add-more-image-steps
FabianVowie:feature/add-pipeline-endpoints
FabianVowie:feature/add-pipeline-loading
FabianVowie:feature/add-pipelines-to-metadata
FabianVowie:feature/add-rate-limiting
FabianVowie:feature/add-rate-limiting-to-readme
FabianVowie:feature/add-settings
FabianVowie:feature/add-storage-layer
FabianVowie:feature/fix-routes
FabianVowie:feature/general-cleanup
FabianVowie:feature/improve-code-stability
FabianVowie:feature/improve-pipeline-abstraction
FabianVowie:feature/make-middlewares-optional
FabianVowie:feature/restructure-pipelines
FabianVowie:feature/start-readme
FabianVowie:feature/update-config-output-format-options
FabianVowie:feature/update-gitignore
FabianVowie:feature/update-route-registration
FabianVowie:main
FabianVowie:pr-feature/add-authorization
FabianVowie:pr-feature/add-commit-hash-to-index-metadata
FabianVowie:pr-feature/add-executable-steps
FabianVowie:pr-feature/add-get-files-endpoints
FabianVowie:pr-feature/add-github-ci
FabianVowie:pr-feature/add-http-image-upload
FabianVowie:pr-feature/add-image-processing
FabianVowie:pr-feature/add-logging
FabianVowie:pr-feature/add-metadata-endpoint
FabianVowie:pr-feature/add-more-image-steps
FabianVowie:pr-feature/add-pipeline-endpoints
FabianVowie:pr-feature/add-pipeline-loading
FabianVowie:pr-feature/add-pipelines-to-metadata
FabianVowie:pr-feature/add-rate-limiting
FabianVowie:pr-feature/add-rate-limiting-to-readme
FabianVowie:pr-feature/add-settings
FabianVowie:pr-feature/add-storage-layer
FabianVowie:pr-feature/enhance-api-responses
FabianVowie:pr-feature/fix-routes
FabianVowie:pr-feature/general-cleanup
FabianVowie:pr-feature/improve-code-stability
FabianVowie:pr-feature/improve-pipeline-abstraction
FabianVowie:pr-feature/make-middlewares-optional
FabianVowie:pr-feature/restructure-pipelines
FabianVowie:pr-feature/start-readme
FabianVowie:pr-feature/update-config-output-format-options
FabianVowie:pr-feature/update-gitignore
FabianVowie:pr-feature/update-route-registration
pull from: FabianVowie:feature/add-authorization
FabianVowie:feature/add-authorization
FabianVowie:feature/add-commit-hash-to-index-metadata
FabianVowie:feature/add-executable-steps
FabianVowie:feature/add-get-files-endpoints
FabianVowie:feature/add-github-ci
FabianVowie:feature/add-http-image-upload
FabianVowie:feature/add-image-processing
FabianVowie:feature/add-logging
FabianVowie:feature/add-metadata-endpoint
FabianVowie:feature/add-more-image-steps
FabianVowie:feature/add-pipeline-endpoints
FabianVowie:feature/add-pipeline-loading
FabianVowie:feature/add-pipelines-to-metadata
FabianVowie:feature/add-rate-limiting
FabianVowie:feature/add-rate-limiting-to-readme
FabianVowie:feature/add-settings
FabianVowie:feature/add-storage-layer
FabianVowie:feature/fix-routes
FabianVowie:feature/general-cleanup
FabianVowie:feature/improve-code-stability
FabianVowie:feature/improve-pipeline-abstraction
FabianVowie:feature/make-middlewares-optional
FabianVowie:feature/restructure-pipelines
FabianVowie:feature/start-readme
FabianVowie:feature/update-config-output-format-options
FabianVowie:feature/update-gitignore
FabianVowie:feature/update-route-registration
FabianVowie:main
FabianVowie:pr-feature/add-authorization
FabianVowie:pr-feature/add-commit-hash-to-index-metadata
FabianVowie:pr-feature/add-executable-steps
FabianVowie:pr-feature/add-get-files-endpoints
FabianVowie:pr-feature/add-github-ci
FabianVowie:pr-feature/add-http-image-upload
FabianVowie:pr-feature/add-image-processing
FabianVowie:pr-feature/add-logging
FabianVowie:pr-feature/add-metadata-endpoint
FabianVowie:pr-feature/add-more-image-steps
FabianVowie:pr-feature/add-pipeline-endpoints
FabianVowie:pr-feature/add-pipeline-loading
FabianVowie:pr-feature/add-pipelines-to-metadata
FabianVowie:pr-feature/add-rate-limiting
FabianVowie:pr-feature/add-rate-limiting-to-readme
FabianVowie:pr-feature/add-settings
FabianVowie:pr-feature/add-storage-layer
FabianVowie:pr-feature/enhance-api-responses
FabianVowie:pr-feature/fix-routes
FabianVowie:pr-feature/general-cleanup
FabianVowie:pr-feature/improve-code-stability
FabianVowie:pr-feature/improve-pipeline-abstraction
FabianVowie:pr-feature/make-middlewares-optional
FabianVowie:pr-feature/restructure-pipelines
FabianVowie:pr-feature/start-readme
FabianVowie:pr-feature/update-config-output-format-options
FabianVowie:pr-feature/update-gitignore
FabianVowie:pr-feature/update-route-registration
32 Commits
main
...
feature/ad
19 changed files with 759 additions and 74 deletions
-
3.gitignore
-
28auth/authorization.go
-
40auth/authorization_test.go
-
18config/example.json
-
4go.mod
-
8go.sum
-
29main.go
-
7main_test.go
-
58pipelines/executable_step.go
-
15pipelines/executable_step_test.go
-
52pipelines/pipeline.go
-
315pipelines/pipeline_test.go
-
19pipelines/step.go
-
61settings/settings.go
-
48settings/settings_test.go
-
57storage/storage.go
-
23storage/storage_test.go
-
BINtests/files/800x500.jpg
-
BINtests/files/900x900.jpg
@ -0,0 +1,28 @@ |
|||
package auth |
|||
|
|||
import ( |
|||
"net/http" |
|||
"strings" |
|||
) |
|||
|
|||
type AuthenticationMiddleware struct { |
|||
secret string |
|||
} |
|||
|
|||
func (middleware AuthenticationMiddleware) Middleware(next http.Handler) http.Handler { |
|||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|||
authToken := r.Header.Get("Authorization") |
|||
|
|||
if authToken == "" || strings.HasPrefix(authToken, "Bearer ") == false || authToken[7:] != middleware.secret { |
|||
http.Error(w, "Forbidden", http.StatusForbidden) |
|||
} else { |
|||
next.ServeHTTP(w, r) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
func CreateAuthenticationMiddleware(secret string) AuthenticationMiddleware { |
|||
return AuthenticationMiddleware{ |
|||
secret: secret, |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
package auth |
|||
|
|||
import ( |
|||
"net/http" |
|||
"net/http/httptest" |
|||
"testing" |
|||
|
|||
"github.com/bxcodec/faker/v3" |
|||
"github.com/stretchr/testify/assert" |
|||
) |
|||
|
|||
func TestAuthorizationMiddleware(t *testing.T) { |
|||
token := faker.Word() |
|||
middleware := CreateAuthenticationMiddleware(token) |
|||
|
|||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
|||
w.WriteHeader(http.StatusOK) |
|||
}) |
|||
|
|||
middlewareHandler := middleware.Middleware(handler) |
|||
|
|||
t.Run("AuthorizationMiddleware returns 403 response when authorization header is incorrect", func(t *testing.T) { |
|||
request, _ := http.NewRequest("GET", "/", nil) |
|||
responseRecorder := httptest.NewRecorder() |
|||
|
|||
middlewareHandler.ServeHTTP(responseRecorder, request) |
|||
|
|||
assert.Equal(t, 403, responseRecorder.Code) |
|||
}) |
|||
|
|||
t.Run("AuthorizationMiddleware continues when authorization header is correct", func(t *testing.T) { |
|||
request, _ := http.NewRequest("GET", "/", nil) |
|||
request.Header.Set("Authorization", "Bearer "+token) |
|||
responseRecorder := httptest.NewRecorder() |
|||
|
|||
middlewareHandler.ServeHTTP(responseRecorder, request) |
|||
|
|||
assert.Equal(t, 200, responseRecorder.Code) |
|||
}) |
|||
} |
@ -0,0 +1,61 @@ |
|||
package settings |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"os" |
|||
"path/filepath" |
|||
|
|||
"github.com/spf13/afero" |
|||
) |
|||
|
|||
const ( |
|||
Local FileSystemType = iota |
|||
) |
|||
|
|||
type FileSystemType int |
|||
|
|||
type Settings struct { |
|||
Endpoint string `json:"endpoint"` |
|||
Token string `json:"token"` |
|||
StorageProvider StorageSettings `json:"storage_provider"` |
|||
} |
|||
|
|||
type StorageSettings struct { |
|||
Type FileSystemType `json:"type"` |
|||
BasePath string `json:"base_path"` |
|||
} |
|||
|
|||
func parseSettings(data []byte) Settings { |
|||
settings := Settings{} |
|||
|
|||
json.Unmarshal(data, &settings) |
|||
|
|||
return settings |
|||
} |
|||
|
|||
func LoadSettings(fileSystem afero.Fs) Settings { |
|||
workingDirectory, _ := os.Getwd() |
|||
path := filepath.Join(workingDirectory, "settings.json") |
|||
|
|||
// Load file and parse file
|
|||
data, err := afero.ReadFile(fileSystem, path) |
|||
|
|||
if err == nil { |
|||
return parseSettings(data) |
|||
} |
|||
|
|||
// If file does not exist, create default settings
|
|||
defaultSettings := Settings{ |
|||
Endpoint: "127.0.0.1:8000", |
|||
Token: "changeme", |
|||
StorageProvider: StorageSettings{ |
|||
Type: Local, |
|||
BasePath: "assets", |
|||
}, |
|||
} |
|||
|
|||
serializedSettings, err := json.MarshalIndent(defaultSettings, "", "\t") |
|||
afero.WriteFile(fileSystem, path, serializedSettings, os.ModePerm) |
|||
|
|||
return defaultSettings |
|||
} |
@ -0,0 +1,48 @@ |
|||
package settings |
|||
|
|||
import ( |
|||
"os" |
|||
"path/filepath" |
|||
"testing" |
|||
|
|||
"github.com/spf13/afero" |
|||
"github.com/stretchr/testify/assert" |
|||
) |
|||
|
|||
func TestSettingsParsing(t *testing.T) { |
|||
const file string = `{ |
|||
"endpoint": "0.0.0.0:8000", |
|||
"token": "foobar", |
|||
"storage_provider": { |
|||
"type": 0, |
|||
"base_path": "assets" |
|||
} |
|||
}` |
|||
|
|||
t.Run("Settings parsing is successful", func(t *testing.T) { |
|||
settings := parseSettings([]byte(file)) |
|||
|
|||
assert.Equal(t, "0.0.0.0:8000", settings.Endpoint) |
|||
assert.Equal(t, "foobar", settings.Token) |
|||
assert.Equal(t, "assets", settings.StorageProvider.BasePath) |
|||
}) |
|||
} |
|||
|
|||
func TestSettingsLoading(t *testing.T) { |
|||
t.Run("Settings loading creates default settings.json when none is present", func(t *testing.T) { |
|||
fileSystem := afero.NewMemMapFs() |
|||
workingDirectory, _ := os.Getwd() |
|||
|
|||
path := filepath.Join(workingDirectory, "settings.json") |
|||
|
|||
// Settings file does not exist in the beginning
|
|||
doesFileExist, _ := afero.Exists(fileSystem, path) |
|||
assert.False(t, doesFileExist) |
|||
|
|||
LoadSettings(fileSystem) |
|||
|
|||
// Settings file should be present after calling LoadSettings
|
|||
doesFileExist, _ = afero.Exists(fileSystem, path) |
|||
assert.True(t, doesFileExist) |
|||
}) |
|||
} |
Before Width: 800 | Height: 500 | Size: 66 KiB After Width: 800 | Height: 500 | Size: 66 KiB |
Before Width: 900 | Height: 900 | Size: 128 KiB After Width: 900 | Height: 900 | Size: 128 KiB |
Write
Preview
Loading…
Cancel
Save
Reference in new issue