Skip to content

Commit ffa9c87

Browse files
figure out auth (#25)
Auth will work via ownership, gated by permissions to create an ownership. Once ownership is granted, only admins and the owner can change permissions. Permissions are: - signal: allowed to send signals to the resource - completion: allowed to be notified of completion - output: allowed to get output - call: allowed to call - lock: allowed to lock - share+: allowed to create new shares - share-: allowed to remove shares and view other shares These permissions can be shared with individual users or roles if the resource authz mode is set to "explicit." If the mode is "auth," then any authenticated user is granted full permissions to the resource. For more fine-grained permissions, the developer should set a role and grant that role to the specific permissions they desire. If the mode is "anon," then any user on the internet is granted full permissions to the resource. The default is "explicit" with no other permissions (only the owner can manage the permissions).
1 parent bf9e764 commit ffa9c87

1,106 files changed

Lines changed: 2460 additions & 536288 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,5 +99,3 @@ composer.phar
9999
*_BASE_*.txt
100100
*_LOCAL_*.txt
101101
*_REMOTE_*.txt
102-
103-
/.git/

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,4 @@ composer.lock
9292

9393
# Ignore DevSpace cache and log folder
9494
.devspace/
95+
bin/dphp-*

.husky/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
npx lint-staged
2-
cd cli && make && cd .. && git add bin/dphp-*
2+
cd cli && make && cd ..
33
vendor/bin/pest

Dockerfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,14 @@ COPY cli/build-php.sh .
5656
RUN BUILD=no ./build-php.sh
5757
RUN ./build-php.sh
5858

59-
COPY cli/go.mod cli/go.sum ./
60-
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
59+
#RUN mkdir -p cli && mv dist cli/
6160

62-
COPY cli/build.sh .
63-
COPY cli/lib ./lib
64-
COPY cli/init ./init
65-
COPY cli/*.go .
61+
COPY cli/go.mod cli/go.sum ./cli/
62+
RUN cd cli && go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
63+
64+
COPY .git/ ./.git/
65+
COPY cli/ ./cli/
66+
WORKDIR /go/src/app/cli
6667
RUN ./build.sh
6768

6869
FROM php:8-zts AS base

cli/Makefile

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@ TARGET := dphp-linux-x86_64
22
BIN_PATH := ../bin
33
DOCKER_IMAGE := builder
44
DOCKER_TARGET := cli-base-alpine
5-
BUILD_PATH := /go/src/app/dist
5+
BUILD_PATH := /go/src/app/cli/dist
66

7-
${BIN_PATH}/${TARGET}: cli.go lib/* go.mod .vendor_modified build.sh init/* build-php.sh
7+
${BIN_PATH}/${TARGET}: cli.go */* go.mod build.sh build-php.sh ../Dockerfile
88
mkdir -p ${BIN_PATH}
99
cd .. && docker build --pull --target ${DOCKER_TARGET} -t ${DOCKER_IMAGE} .
1010
docker create --name builder builder || ( docker rm -f builder && false )
1111
docker cp ${DOCKER_IMAGE}:${BUILD_PATH}/${TARGET} ${BIN_PATH}/${TARGET} || ( docker rm -f builder && false )
1212
docker rm -f builder
1313
upx -9 --force-pie ../bin/dphp-*
14-
15-
# This will capture the most recently modified time among all files under vendor/ recursively
16-
VENDOR_TIMESTAMP := $(shell find vendor -type f -print0 | xargs -0 stat -c '%Y' | sort -nr | head -n1)
17-
18-
.vendor_modified:
19-
@echo ${VENDOR_TIMESTAMP} > .vendor_modified

cli/appcontext/auth.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package appcontext
2+
3+
type ContextKey struct{}
4+
5+
var CurrentUserKey ContextKey

cli/auth/createPermissions.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package auth
2+
3+
type CreatePermissions struct {
4+
Mode Mode `json:"mode"`
5+
Limits struct {
6+
User int `json:"user"`
7+
Role int `json:"role"`
8+
Global int `json:"global"`
9+
} `json:"limits"`
10+
Users []UserId `json:"users"`
11+
Roles []Role `json:"roles"`
12+
}

cli/auth/keys.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package auth
2+
3+
import (
4+
"context"
5+
"durable_php/appcontext"
6+
"durable_php/config"
7+
"encoding/base64"
8+
"fmt"
9+
"github.com/golang-jwt/jwt/v4"
10+
"net/http"
11+
"strings"
12+
"time"
13+
)
14+
15+
func getActiveKey(config *config.Config) []byte {
16+
key := config.Extensions.Authz.Secrets[len(config.Extensions.Authz.Secrets)-1]
17+
decoded, err := base64.StdEncoding.DecodeString(key)
18+
if err != nil {
19+
panic(err)
20+
}
21+
return decoded
22+
}
23+
24+
func DecorateContextWithUser(ctx context.Context, user *User) context.Context {
25+
return context.WithValue(ctx, appcontext.CurrentUserKey, user)
26+
}
27+
28+
func ExtractUser(r *http.Request, config *config.Config) (user *User, ok bool) {
29+
tokenString := r.Header.Get("Authorization")
30+
if tokenString == "" {
31+
return nil, false
32+
}
33+
34+
tokenParts := strings.SplitN(tokenString, " ", 2)
35+
if tokenParts[0] != "Bearer" {
36+
return nil, false
37+
}
38+
39+
token, err := jwt.Parse(tokenParts[1], func(token *jwt.Token) (interface{}, error) {
40+
if token.Method.Alg() != jwt.SigningMethodHS256.Alg() {
41+
return nil, fmt.Errorf("unexpected signing method")
42+
}
43+
44+
return getActiveKey(config), nil
45+
}, jwt.WithValidMethods([]string{"HS256"}))
46+
if err != nil {
47+
return nil, false
48+
}
49+
50+
getRoles := func(roles []interface{}) []Role {
51+
rolesSlice := make([]Role, len(roles))
52+
for i, r := range roles {
53+
rolesSlice[i] = Role(r.(string))
54+
}
55+
return rolesSlice
56+
}
57+
58+
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
59+
userId := claims["sub"].(string)
60+
rol := claims["roles"].([]interface{})
61+
return &User{
62+
UserId: UserId(userId),
63+
Roles: getRoles(rol),
64+
}, true
65+
}
66+
67+
return nil, false
68+
}
69+
70+
func CreateUser(userId UserId, role []Role, config *config.Config) (string, error) {
71+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
72+
"sub": userId,
73+
"exp": time.Now().Add(72 * time.Hour).Unix(),
74+
"iat": time.Now().Add(-5 * time.Minute).Unix(),
75+
"roles": role,
76+
})
77+
78+
signedString, err := token.SignedString(getActiveKey(config))
79+
if err != nil {
80+
return "", err
81+
}
82+
83+
return signedString, nil
84+
}

0 commit comments

Comments
 (0)