diff --git a/README.md b/README.md index ced12eef..ff764348 100644 --- a/README.md +++ b/README.md @@ -200,4 +200,91 @@ network: "testnet" bee: bee-api-endpoint: http://localhost:1633 # bee running on mainnet postage-batch-id: -``` \ No newline at end of file +``` + +### Integrating git with dfs + +To integrate git with dfs, we need to set the `git` configuration in the config file. We only need to set the credential helper for local git repositories. + +We create a file `.dfs-credentials` with the following content at any given location +``` +#!/bin/bash +token_file="" # this needs to be absolute path + +username="" +password="" + +dfs="" # http://localhost:9090 for local running fairOS-dfs server + +# Function to get the access token using the username and password +get_access_token() { + local response=$(curl -s -X POST "$dfs/v2/user/login" -H "Content-Type: application/json" -d "{\"userName\": \"$username\", \"password\": \"$password\"}") + access_token=$(echo "$response" | jq -r '.accessToken') + # check if response has access token + if [ "$access_token" == "null" ]; then + exit 1 + fi + echo "$access_token" > "$token_file" + echo "$access_token" +} + +get_saved_access_token() { + if [[ -f "$token_file" ]]; then + local saved_token=$(sed -n '1p' "$token_file") + if [ "$saved_token" == "null" ] || [ "$saved_token" == "" ]; then + return 1 + fi + local response=$(curl --write-out '%{http_code}' --silent --output /dev/null -s -X POST "$dfs/v1/user/stat" -H "Content-Type: application/json" -H "Authorisation: Bearer $saved_token" ) + # check if response had success http code + if [[ response -eq 200 ]]; then + echo "$saved_token" + return 0 + else + rm "$token_file" + return 1 + fi + fi + return 1 +} + +access_token=$(get_saved_access_token) +if [[ $? -ne 0 ]]; then + access_token=$(get_access_token) +fi +echo "username=$username" +echo "password=$access_token" + +exit 0 +``` + +After creating this file, we need to set the `credential.helper` in the git configuration + +``` +git config --local credential.helper "" +``` + +#### How to push to dfs + +Currently, we only support pushing once, so its sort of archive. We can push the git repository to dfs using the following command + +``` +git init # initialize the git repository, run this inside the directory that you want to push to dfs +git add . # add all the files to the git repository +git commit -m "Initial commit" # commit the changes +git remote add origin /v1/git//.git # add the remote origin +git config --local credential.helper "" # set the credential helper +git push -u origin master # push the changes to the remote origin +``` + +### How to clone from dfs + +``` +git config --local credential.helper "" +git clone /v1/git//.git +``` + +NOTE: Before pushing into a pod, we have to first create a pod if it does not exist. A pod can not be used as two different repos. +Dfs stores the files of the repo as a git pack file. So, we cannot access each file of the repo individually. although we can access other files from dfs api as expected. + + + diff --git a/cmd/dfs/cmd/dev.go b/cmd/dfs/cmd/dev.go index da3b79ce..48e56d98 100644 --- a/cmd/dfs/cmd/dev.go +++ b/cmd/dfs/cmd/dev.go @@ -60,7 +60,7 @@ func startDevServer() { dfsApi := dfs.NewMockDfsAPI(mockClient, users, logger) handler = api.NewMockHandler(dfsApi, logger, []string{"http://localhost:3000"}) defer handler.Close() - httpPort = ":9090" + httpPort = ":9093" pprofPort = ":9091" srv := startHttpService(logger) fmt.Printf("Server running at:http://127.0.0.1%s\n", httpPort) diff --git a/cmd/dfs/cmd/server.go b/cmd/dfs/cmd/server.go index 51781ef5..c0404667 100644 --- a/cmd/dfs/cmd/server.go +++ b/cmd/dfs/cmd/server.go @@ -447,6 +447,13 @@ func startHttpService(logger logging.Logger) *http.Server { docRouter.HandleFunc("/entry/get", handler.DocEntryGetHandler).Methods("GET") docRouter.HandleFunc("/entry/del", handler.DocEntryDelHandler).Methods("DELETE") + gitRouter := baseRouter.PathPrefix("/git/").Subrouter() + gitRouter.Use(handler.GitAuthMiddleware) + gitRouter.HandleFunc("/{user}/{repo}.git/HEAD", handler.GitInfoRef).Methods("GET") + gitRouter.HandleFunc("/{user}/{repo}.git/info/refs", handler.GitInfoRef).Methods("GET") + gitRouter.HandleFunc("/{user}/{repo}.git/git-upload-pack", handler.GitUploadPack).Methods("POST") + gitRouter.HandleFunc("/{user}/{repo}.git/git-receive-pack", handler.GitReceivePack).Methods("POST") + var origins []string for _, c := range corsOrigins { c = strings.TrimSpace(c) diff --git a/go.mod b/go.mod index cf165641..c4031737 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/fairdatasociety/fairOS-dfs go 1.21 require ( - github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/btcsuite/btcd/btcec/v2 v2.3.3 github.com/c-bata/go-prompt v0.2.6 github.com/dustin/go-humanize v1.0.1 - github.com/ethereum/go-ethereum v1.13.14 + github.com/ethereum/go-ethereum v1.14.0 github.com/ethersphere/bee/v2 v2.0.0 github.com/ethersphere/bmt v0.1.4 github.com/fairdatasociety/fairOS-dfs-utils v0.0.0-20221230123929-aec4ed8b854d @@ -25,15 +25,15 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/swaggo/http-swagger v1.3.4 github.com/swaggo/swag v1.16.3 github.com/tinygrasshopper/bettercsv v0.0.1 github.com/tyler-smith/go-bip39 v1.1.0 github.com/wealdtech/go-ens/v3 v3.6.0 go.uber.org/goleak v1.3.0 - golang.org/x/crypto v0.19.0 - golang.org/x/term v0.17.0 + golang.org/x/crypto v0.22.0 + golang.org/x/term v0.19.0 gopkg.in/yaml.v2 v2.4.0 resenje.org/jsonhttp v0.2.3 ) @@ -52,11 +52,11 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect - github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethersphere/bee v1.10.0 // indirect github.com/ethersphere/go-price-oracle-abi v0.2.0 // indirect github.com/ethersphere/go-storage-incentives-abi v0.6.2 // indirect @@ -73,7 +73,8 @@ require ( github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.4.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect @@ -110,6 +111,7 @@ require ( github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/onsi/gomega v1.27.10 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -120,6 +122,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect @@ -143,13 +146,13 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.15.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect diff --git a/go.sum b/go.sum index 2140b591..b40b03e4 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6 github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.3 h1:kYNaWFvOw6xvqP0vR20RP1Zq1DVMBxEO8QN5d1/EfNg= github.com/btcsuite/btcd v0.22.3/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0= +github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -45,16 +45,14 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= -github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= -github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= -github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= +github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= +github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -71,8 +69,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0q github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= -github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -93,10 +91,10 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= -github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= -github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.0 h1:xRWC5NlB6g1x7vNy4HDBLuqVNbtLrc7v8S6+Uxim1LU= +github.com/ethereum/go-ethereum v1.14.0/go.mod h1:1STrq471D0BQbCX9He0hUj4bHxX2k6mt5nOQJhDNOJ8= github.com/ethersphere/bee v1.10.0 h1:GVMO/aTgxNFX6IZyBYJKoR8OFnEjJjQnuQPuY/M75zs= github.com/ethersphere/bee v1.10.0/go.mod h1:zy0U2o4EvOKiRKb67TdZnSOP8tTnrc62+bsJCgqeEPs= github.com/ethersphere/bee/v2 v2.0.0 h1:hGSSIKpXRa/uP9lYW7tecAoEWFEDzGO/dJo5UhkRllc= @@ -132,6 +130,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqG github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= +github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= @@ -182,18 +182,16 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= @@ -386,8 +384,9 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= @@ -430,8 +429,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -469,8 +468,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -538,14 +538,14 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -557,16 +557,16 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -596,11 +596,11 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -615,24 +615,20 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/api/file_status.go b/pkg/api/file_status.go index 56d5c6ee..c59e776c 100644 --- a/pkg/api/file_status.go +++ b/pkg/api/file_status.go @@ -1,6 +1,7 @@ package api import ( + "errors" "net/http" "github.com/fairdatasociety/fairOS-dfs/pkg/auth" @@ -83,12 +84,12 @@ func (h *Handler) FileStatusHandler(w http.ResponseWriter, r *http.Request) { // status of file t, p, s, err := h.dfsAPI.StatusFile(driveName, podFileWithPath, sessionId, isGroup) if err != nil { - if err == dfs.ErrPodNotOpen { + if errors.Is(err, dfs.ErrPodNotOpen) { h.logger.Errorf("status: %v", err) jsonhttp.BadRequest(w, "status: "+err.Error()) return } - if err == file.ErrFileNotFound { + if errors.Is(err, file.ErrFileNotFound) { h.logger.Errorf("status: %v", err) jsonhttp.NotFound(w, "status: "+err.Error()) return diff --git a/pkg/api/git.go b/pkg/api/git.go new file mode 100644 index 00000000..bcf06afa --- /dev/null +++ b/pkg/api/git.go @@ -0,0 +1,207 @@ +package api + +import ( + "bytes" + "errors" + "fmt" + "io" + "net/http" + "strings" + + "github.com/fairdatasociety/fairOS-dfs/pkg/auth" + "github.com/fairdatasociety/fairOS-dfs/pkg/auth/jwt" + "github.com/fairdatasociety/fairOS-dfs/pkg/file" + "github.com/gorilla/mux" + "resenje.org/jsonhttp" +) + +var ( + refFile = "refFile" +) + +// GitAuthMiddleware checks the Authorization header for git auth credentials +func (h *Handler) GitAuthMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + authHeader := r.Header.Get("Authorization") + if authHeader == "" { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Authorization required", http.StatusUnauthorized) + return + } + + _, err := jwt.GetSessionIdFromGitRequest(r) + if err != nil { + http.Error(w, "Invalid username or password", http.StatusUnauthorized) + return + } + + next.ServeHTTP(w, r) + }) +} + +func (h *Handler) GitInfoRef(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + vars := mux.Vars(r) + pod := vars["repo"] + serviceType := r.FormValue("service") + + // check if pod exists + if _, err = h.dfsAPI.OpenPod(pod, sessionId); err != nil { + h.logger.Errorf("IsPodExist failed: ", err) + jsonhttp.BadRequest(w, &response{Message: "Repo does not exist"}) + return + } + refLine := "" + // check if ref file exists + reader, _, err := h.dfsAPI.DownloadFile(pod, fmt.Sprintf("/%s", refFile), sessionId, false) + if err == nil { + defer reader.Close() + refData, _ := io.ReadAll(reader) + if len(refData) != 0 { + refLine = fmt.Sprintf("%s\n", refData) + } + } + + w.Header().Set("Expires", "Fri, 01 Jan 2080 00:00:00 GMT") + w.Header().Set("Pragma", "no-cache") + w.Header().Set("Cache-Control", "no-cache, max-age=0, must-revalidate") + w.Header().Set("Content-Type", fmt.Sprintf("application/x-%s-advertisement", serviceType)) + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(packetWrite("# service=" + serviceType + "\n"))) + _, _ = w.Write([]byte("0000")) + if refLine != "" { + _, _ = w.Write([]byte(packetWrite(refLine))) + } else { + capabilities := "report-status object-format=sha1" + emptyList := fmt.Sprintf("0000000000000000000000000000000000000000 capabilities^{}\000%s\n", capabilities) + _, _ = w.Write([]byte(packetWrite(emptyList))) + } + _, _ = w.Write([]byte("0000")) +} + +func (h *Handler) GitUploadPack(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + vars := mux.Vars(r) + pod := vars["repo"] + w.Header().Set("Content-Type", "application/x-git-upload-pack-result") + + reader, _, err := h.dfsAPI.DownloadFile(pod, fmt.Sprintf("/%s", refFile), sessionId, false) + if err != nil { + h.logger.Error("ref not found: ", err) + jsonhttp.BadRequest(w, &response{Message: "ref not found"}) + return + } + commitDetailsBytes, err := io.ReadAll(reader) + if err != nil { + h.logger.Error("ref not found: ", err) + jsonhttp.BadRequest(w, &response{Message: "ref not found"}) + return + } + commitDetailsArr := strings.Split(string(commitDetailsBytes), " ") + + packReader, _, err := h.dfsAPI.DownloadFile(pod, fmt.Sprintf("/%s", commitDetailsArr[0]), sessionId, false) + if err != nil { + h.logger.Error("ref not found: ", err) + jsonhttp.BadRequest(w, &response{Message: "ref not found"}) + return + } + _, _ = w.Write([]byte(packetWrite(fmt.Sprintf("ACK %s\n", commitDetailsArr[0])))) + _, err = io.Copy(w, packReader) + if err != nil { + h.logger.Errorf("download: %v", err) + w.Header().Set("Content-Type", " application/json") + jsonhttp.InternalServerError(w, "download: "+err.Error()) + } +} + +func (h *Handler) GitReceivePack(w http.ResponseWriter, r *http.Request) { + sessionId, err := auth.GetSessionIdFromGitRequest(r) + if err != nil { + h.logger.Errorf("sessionId parse failed: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + if sessionId == "" { + h.logger.Error("sessionId not set: ", err) + jsonhttp.BadRequest(w, &response{Message: ErrUnauthorized.Error()}) + return + } + + defer r.Body.Close() + buf := new(bytes.Buffer) + if _, err := io.Copy(buf, r.Body); err != nil { + h.logger.Errorf("Error reading request body: %v", err) + http.Error(w, fmt.Sprintf("Error reading request body: %v", err), http.StatusInternalServerError) + return + } + + packIndex := bytes.Index(buf.Bytes(), []byte("PACK")) + if packIndex == -1 { + h.logger.Errorf("PACK signature not found in request body") + http.Error(w, "PACK signature not found in request body", http.StatusBadRequest) + return + } + commitDetails := strings.TrimSpace(buf.String()[:packIndex]) + commitDetailsArr := strings.Split(commitDetails, " ") + + vars := mux.Vars(r) + pod := vars["repo"] + newHash, ref := commitDetailsArr[1], commitDetailsArr[2] + + _, _, _, err = h.dfsAPI.StatusFile(pod, fmt.Sprintf("/%s", refFile), sessionId, false) + if err != nil && !errors.Is(err, file.ErrFileNotFound) { + h.logger.Errorf("Error checking commit status: %v", err) + http.Error(w, fmt.Sprintf("Error checking file status: %v", err), http.StatusInternalServerError) + return + } + if err == nil { + h.logger.Errorf("Cannot push. ref file already exists") + http.Error(w, "Cannot push", http.StatusInternalServerError) + return + } + err = h.dfsAPI.UploadFile(pod, refFile, sessionId, int64(len(newHash+" "+ref)), strings.NewReader(newHash+" "+ref), "/", "", file.MinBlockSize, 0, false, false) + if err != nil { + h.logger.Errorf("Error uploading commit: %v", err) + http.Error(w, fmt.Sprintf("Error uploading file: %v", err), http.StatusInternalServerError) + return + } + + packData := bytes.NewReader(buf.Bytes()[packIndex:]) + err = h.dfsAPI.UploadFile(pod, newHash, sessionId, int64(packData.Len()), packData, "/", "", file.MinBlockSize, 0, false, false) + if err != nil { + h.logger.Errorf("Error uploading packfile: %v", err) + http.Error(w, fmt.Sprintf("Error uploading file: %v", err), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/x-git-receive-pack-result") + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(packetWrite("unpack ok\n"))) + _, _ = w.Write([]byte(packetWrite("ok " + ref + "\n"))) + _, _ = w.Write([]byte("0000")) +} + +func packetWrite(data string) string { + length := len(data) + 4 // 4 bytes for the length itself + return fmt.Sprintf("%04x%s", length, data) +} diff --git a/pkg/api/login_middleware.go b/pkg/api/login_middleware.go index 4a10fbfd..469bc029 100644 --- a/pkg/api/login_middleware.go +++ b/pkg/api/login_middleware.go @@ -17,6 +17,7 @@ limitations under the License. package api import ( + "errors" "net/http" "time" @@ -31,10 +32,11 @@ import ( // proceed for execution. func (h *Handler) LoginMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sessionId, err := jwt.GetSessionIdFromToken(r) - if err != nil && err != jwt.ErrNoTokenInRequest { + + sessionId, err := jwt.GetSessionIdFromRequest(r) + if err != nil && !errors.Is(err, jwt.ErrNoTokenInRequest) { h.logger.Errorf("jwt: invalid token: %v", err) - jsonhttp.BadRequest(w, &response{Message: "jwt: invalid token"}) + jsonhttp.Unauthorized(w, &response{Message: "jwt: invalid token"}) return } @@ -46,7 +48,7 @@ func (h *Handler) LoginMiddleware(next http.Handler) http.Handler { sessionId, loginTimeout, err := cookie.GetSessionIdAndLoginTimeFromCookie(r) if err != nil { h.logger.Errorf("cookie: invalid cookie: %v", err) - jsonhttp.BadRequest(w, &response{Message: "cookie: invalid cookie: " + err.Error()}) + jsonhttp.Unauthorized(w, &response{Message: "cookie: invalid cookie: " + err.Error()}) return } @@ -54,14 +56,14 @@ func (h *Handler) LoginMiddleware(next http.Handler) http.Handler { loginTime, err := time.Parse(time.RFC3339, loginTimeout) if err != nil { h.logger.Errorf("cookie: invalid login timeout") - jsonhttp.BadRequest(w, &response{Message: "cookie: invalid login timeout"}) + jsonhttp.Unauthorized(w, &response{Message: "cookie: invalid login timeout"}) return } if loginTime.Before(time.Now()) { err = h.dfsAPI.LogoutUser(sessionId) if err == nil { h.logger.Errorf("Logging out as cookie login timeout expired") - jsonhttp.BadRequest(w, &response{Message: "logging out as cookie login timeout expired"}) + jsonhttp.Unauthorized(w, &response{Message: "logging out as cookie login timeout expired"}) return } } diff --git a/pkg/auth/jwt/jwt.go b/pkg/auth/jwt/jwt.go index 0cbe3c9d..8d95bf8e 100644 --- a/pkg/auth/jwt/jwt.go +++ b/pkg/auth/jwt/jwt.go @@ -1,6 +1,7 @@ package jwt import ( + "encoding/base64" "errors" "fmt" "net/http" @@ -34,7 +35,7 @@ func GenerateToken(sessionId string) (string, error) { claims := Claims{ jwt.RegisteredClaims{ ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), - Issuer: "test", + Issuer: "dfs", }, sessionId, } @@ -62,8 +63,8 @@ func parse(tokenStr string) (string, error) { } } -// GetSessionIdFromToken extracts sessionId from http.Request Auth header -func GetSessionIdFromToken(request *http.Request) (sessionId string, err error) { +// GetSessionIdFromRequest extracts sessionId from http.Request Auth header +func GetSessionIdFromRequest(request *http.Request) (sessionId string, err error) { authHeader := request.Header.Get("Authorization") parts := strings.Split(authHeader, "Bearer") if len(parts) != 2 { @@ -79,3 +80,45 @@ func GetSessionIdFromToken(request *http.Request) (sessionId string, err error) } return parse(tokenStr) } + +// GetSessionIdFromGitRequest extracts sessionId from http.Request Auth header for git apis +func GetSessionIdFromGitRequest(request *http.Request) (sessionId string, err error) { + authHeader := request.Header.Get("Authorization") + if authHeader == "" { + return "", ErrNoTokenInRequest + } + parts := strings.Split(authHeader, "Basic") + if len(parts) != 2 { + return "", ErrNoTokenInRequest + } + + payload, err := base64.StdEncoding.DecodeString(strings.TrimSpace(parts[1])) + if err != nil { + return "", err + } + pair := strings.SplitN(string(payload), ":", 2) + tokenStr := strings.TrimSpace(pair[1]) + if len(tokenStr) < 1 { + return "", ErrNoTokenInRequest + } + if tokenStr == "" { + return "", ErrNoTokenInRequest + } + return parse(tokenStr) +} + +// GetSessionIdFromToken extracts sessionId from an actual token +func GetSessionIdFromToken(token string) (sessionId string, err error) { + if len(token) == 0 { + return "", ErrNoTokenInRequest + } + + tokenStr := strings.TrimSpace(token) + if len(tokenStr) < 1 { + return "", ErrNoTokenInRequest + } + if tokenStr == "" { + return "", ErrNoTokenInRequest + } + return parse(tokenStr) +} diff --git a/pkg/auth/utils.go b/pkg/auth/utils.go index d9b748e7..c5deaf87 100644 --- a/pkg/auth/utils.go +++ b/pkg/auth/utils.go @@ -22,7 +22,7 @@ func GetUniqueSessionId() string { func GetSessionIdFromRequest(r *http.Request) (string, error) { sessionId, err := cookie.GetSessionIdFromCookie(r) if err != nil { - sessionId, err = jwt.GetSessionIdFromToken(r) + sessionId, err = jwt.GetSessionIdFromRequest(r) if err != nil { return "", err } @@ -30,3 +30,12 @@ func GetSessionIdFromRequest(r *http.Request) (string, error) { return sessionId, err } + +func GetSessionIdFromGitRequest(r *http.Request) (string, error) { + sessionId, err := jwt.GetSessionIdFromGitRequest(r) + if err != nil { + return "", err + } + + return sessionId, err +} diff --git a/pkg/dfs/pod_api.go b/pkg/dfs/pod_api.go index 611766e5..1fad4715 100644 --- a/pkg/dfs/pod_api.go +++ b/pkg/dfs/pod_api.go @@ -99,7 +99,6 @@ func (a *API) DeletePod(podName, sessionId string) error { // OpenPod opens a pod func (a *API) OpenPod(podName, sessionId string) (*pod.Info, error) { - fmt.Println("OpenPod 1") // get the loggedin user information ui := a.users.GetLoggedInUserInfo(sessionId) if ui == nil { diff --git a/pkg/dir/modify_dir_entry.go b/pkg/dir/modify_dir_entry.go index ebceb3b5..4f47e38b 100644 --- a/pkg/dir/modify_dir_entry.go +++ b/pkg/dir/modify_dir_entry.go @@ -43,7 +43,6 @@ func (d *Directory) AddEntryToDir(parentDir, podPassword, itemToAdd string, isFi if err != nil { return ErrDirectoryNotPresent } - // add file or directory entry if isFile { itemToAdd = "_F_" + itemToAdd diff --git a/pkg/pod/new.go b/pkg/pod/new.go index de98b0e6..26bd0aec 100644 --- a/pkg/pod/new.go +++ b/pkg/pod/new.go @@ -20,7 +20,6 @@ import ( "bytes" "encoding/hex" "encoding/json" - "fmt" "io" "github.com/ethereum/go-ethereum/crypto" @@ -212,7 +211,6 @@ func (p *Pod) loadUserPodsV2() (*List, error) { } func (p *Pod) storeUserPodsV2(podList *List) error { - fmt.Println("storeUserPodsV2") data, err := json.Marshal(podList) if err != nil { return err diff --git a/pkg/test/group_new_test.go b/pkg/test/group_new_test.go index 0cca8826..b28f4fc8 100644 --- a/pkg/test/group_new_test.go +++ b/pkg/test/group_new_test.go @@ -18,7 +18,6 @@ package test_test import ( "errors" - "fmt" "io" "testing" @@ -155,7 +154,6 @@ func TestGroupNew(t *testing.T) { mockAcl := acl.NewACL(mockClient, fd, logger) group := pod.NewGroup(mockClient, fd, acc, mockAcl, logger) groupName1, _ := utils.GetRandString(10) - fmt.Println("group name", groupName1) _, err = group.CreateGroup(groupName1) if err != nil { t.Fatalf("error creating group %s: %s", groupName1, err.Error()) @@ -263,7 +261,6 @@ func TestGroupNew(t *testing.T) { if err != nil { t.Fatal(err) } - fmt.Println("permission", perm) if perm != acl.PermissionWrite { t.Fatal("permission does not match") }