Skip to content

Commit

Permalink
Merge pull request #650 from fairDataSociety/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
asabya authored Oct 29, 2024
2 parents 88941b6 + 54c22d2 commit a95368e
Show file tree
Hide file tree
Showing 135 changed files with 7,638 additions and 1,915 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21.4'
go-version: '1.22.0'
- name: Checkout
uses: actions/checkout@v3
with:
Expand Down
9 changes: 8 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go: ['1.21.4']
go: ['1.22.0']
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Setup Go
Expand All @@ -41,6 +41,13 @@ jobs:
- name: Lint
if: matrix.os == 'ubuntu-latest'
run: make lint
- name: Set up port range and TIME_WAIT
if: matrix.os == 'windows-latest'
run: |
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'TcpTimedWaitDelay' -Type DWord -Value 3 -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'MaxUserPort' -Type DWord -Value 65534 -Force
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' -Name 'MaxFreeTcbs' -Type DWord -Value 65536 -Force
shell: pwsh
- name: Vet
if: matrix.os == 'ubuntu-latest'
run: make vet
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21.4'
go-version: '1.22.0'
- name: Checkout
uses: actions/checkout@v3
with:
Expand All @@ -45,7 +45,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21.4'
go-version: '1.22.0'
- name: Checkout
uses: actions/checkout@v3
with:
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21.4'
go-version: '1.22.0'
- name: Checkout
uses: actions/checkout@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ cover.out

fairos.aar
fairos-sources.jar
fairos.wasm
fairos.wasm*
fairos.wasm.gz
5 changes: 5 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
run:
timeout: 10m
concurrency: 4
tests: false

linters:
enable:
- misspell
- gofmt
- unconvert
issues:
exclude-dirs: ["wasm"]
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GO ?= go
GOLANGCI_LINT ?= $$($(GO) env GOPATH)/bin/golangci-lint
GOLANGCI_LINT_VERSION ?= v1.55.2
GOLANGCI_LINT_VERSION ?= v1.61.0
GOGOPROTOBUF ?= protoc-gen-gogofaster
GOGOPROTOBUF_VERSION ?= v1.3.1

Expand All @@ -24,7 +24,7 @@ dist:

.PHONY: lint
lint: linter
$(GOLANGCI_LINT) run --skip-dirs wasm
$(GOLANGCI_LINT) run

.PHONY: linter
linter:
Expand All @@ -33,7 +33,7 @@ linter:
.PHONY: swagger
swagger:
which swag || ( echo "install swag for your system from https://github.com/swaggo/swag" && exit 1)
swag init -g ./cmd/server.go -d cmd/dfs,pkg/api,cmd/common,pkg/dir,pkg/file,pkg/pod,pkg/user,pkg/collection -o ./swagger
swag init -g ./cmd/server.go -d cmd/dfs,pkg/api,cmd/common,pkg/dir,pkg/file,pkg/pod,pkg/user,pkg/collection,pkg/act,pkg/utils -o ./swagger

.PHONY: vet
vet:
Expand Down
103 changes: 102 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ The user can share files in his pod with any other user just like in other centr

Pod creation is cheap. A user can create multiple pods and use it to organise his data. for ex: Personal-Pod, Applications-Pod etc.

## (NEW) Access Control Trie (ACT) Integration
### Overview
We have introduced a new feature that integrates Swarm's Access Control Trie (ACT) into fairOS-dfs to enable user-based access control. This enhancement allows for more granular permissions and secure data sharing among users.

### What is ACT?
The Access Control Trie (ACT) is a mechanism provided by Swarm for managing access permissions to resources stored on the Swarm network. It allows publishers to grant or revoke access to specific grantees.

### How is ACT Integrated into fairOS-dfs?
In the native Swarm implementation, ACT is node-based and lacks the concept of users, which is not suitable for user-centric applications like fairOS-dfs. We have integrated ACT in such a way that:

- User-Based Initialization: Access control is initialized with a user's key, tying permissions directly to user identities.
- Grantee Management: Users can be added as grantees by their public keys, allowing specific users to access shared resources.
- Secure Sharing: Instead of sharing the pod sharing reference directly, we wrap that reference using ACT and share the wrapped actRef. This ensures that only authorized users can access the shared content, even if the actRef is obtained by others.

## (NEW) What is a group?
A group is a shared drive created by a user. It is basically a pod, but on steroids. Group Owner can add members and update permissions. Members with "write" permission can create and store any number of files or directories in a group.

Expand Down Expand Up @@ -200,4 +214,91 @@ network: "testnet"
bee:
bee-api-endpoint: http://localhost:1633 # bee running on mainnet
postage-batch-id: <BATCH>
```
```

### 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="<ABSOLUTE PATH FOR STRING ACCESS TOKEN>" # this needs to be absolute path
username="<USERNAME>"
password="<PASSWORD>"
dfs="<FAIROS-DFS SERVER URL>" # 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 "<Absolute path to .dfs-credentials file>"
```

#### 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 <DFS SERVER>/v1/git/<USERNAME>/<PODNAME>.git # add the remote origin
git config --local credential.helper "<Absolute path to .dfs-credentials file>" # 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 "<Absolute path to .dfs-credentials file>"
git clone <DFS SERVER>/v1/git/<USERNAME>/<PODNAME>.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.



6 changes: 6 additions & 0 deletions cmd/common/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ type UserLoginRequest struct {
Password string `json:"password,omitempty"`
}

// UserSignatureLoginRequest is the request body for user login with signature
type UserSignatureLoginRequest struct {
Signature string `json:"signature,omitempty"`
Password string `json:"password,omitempty"`
}

// PodRequest is the request body for pod creation
type PodRequest struct {
PodName string `json:"podName,omitempty"`
Expand Down
126 changes: 126 additions & 0 deletions cmd/dfs-cli/cmd/act.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package cmd

import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strings"

"github.com/fairdatasociety/fairOS-dfs/pkg/utils"

"github.com/fairdatasociety/fairOS-dfs/pkg/api"
)

func actNew(actName, publicKey string) {
url := fmt.Sprintf("%s/%s?grantee=%s", actGrantee, actName, publicKey)
data, err := fdfsAPI.postReq(http.MethodPost, url, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actGrantRevoke(actName, key, action string) {
url := fmt.Sprintf("%s/%s", actGrantee, actName)
switch action {
case "grant":
url = fmt.Sprintf("%s?grant=%s", url, key)
case "revoke":
url = fmt.Sprintf("%s?revoke=%s", url, key)
default:
fmt.Println("invalid action")
}
data, err := fdfsAPI.postReq(http.MethodPatch, url, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actListGrantees(actName string) {
url := fmt.Sprintf("%s/%s", actGrantee, actName)
data, err := fdfsAPI.postReq(http.MethodGet, url, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actPodShare(actName, podName string) {
url := fmt.Sprintf("%s/%s/%s", actSharePod, actName, podName)
data, err := fdfsAPI.postReq(http.MethodPost, url, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actListAll() {
data, err := fdfsAPI.postReq(http.MethodGet, actList, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actPodsShared(actName string) {
url := fmt.Sprintf("%s/%s", actSharedPods, actName)
data, err := fdfsAPI.postReq(http.MethodGet, url, nil)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}

func actSaveSharedPod(actName, reference, topic, owner, ownerPublicKey string) {
url := fmt.Sprintf("%s/%s", actSavePod, actName)
topicBytes, err := base64.StdEncoding.DecodeString(topic)
if err != nil {
fmt.Println("could not save act: ", err)
return
}
content := &api.Content{
Reference: reference,
Topic: topicBytes,
Owner: owner,
OwnerPublicKey: ownerPublicKey,
}
data, err := json.Marshal(content)
if err != nil {
fmt.Println("could not save act: ", err)
return
}
resp, err := fdfsAPI.postReq(http.MethodPost, url, data)
if err != nil {
fmt.Println("could not create act: ", err)
return
}
message := strings.ReplaceAll(string(resp), "\n", "")
fmt.Println(message)
}

func actOpenSharedPod(actName string) {
url := fmt.Sprintf("%s/%s", actOpenPod, actName)
data, err := fdfsAPI.postReq(http.MethodPost, url, nil)
if err != nil {
fmt.Println("could not open act: ", err)
return
}
currentPod = actName
currentDirectory = utils.PathSeparator
message := strings.ReplaceAll(string(data), "\n", "")
fmt.Println(message)
}
Loading

0 comments on commit a95368e

Please sign in to comment.