Skip to content
This repository has been archived by the owner on Oct 28, 2023. It is now read-only.

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Kcrong committed Oct 3, 2023
1 parent a8cf557 commit 2c5c2d0
Show file tree
Hide file tree
Showing 46 changed files with 5,253 additions and 521 deletions.
4 changes: 4 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
inpackage: True
with-expecter: True
testonly: True
include-auto-generated: False
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ update:
@go get -u all
go mod tidy

.PHONY: generate
generate:
@go install github.com/vektra/mockery/[email protected]
mockery

.PHONY: models
models:
@go install github.com/volatiletech/sqlboiler/v4@latest
Expand Down
58 changes: 57 additions & 1 deletion db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,14 @@ CREATE TABLE public.auth_attempt_log (
auth_attempt_log_theme_spec_path text NOT NULL,
auth_attempt_log_opennds_version character varying(20) NOT NULL,
auth_attempt_log_created_at timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
auth_attempt_log_updated_at timestamp without time zone
auth_attempt_log_updated_at timestamp without time zone,
auth_attempt_log_rhid text NOT NULL,
auth_attempt_log_session_length_minutes bigint NOT NULL,
auth_attempt_log_upload_rate_threshold bigint NOT NULL,
auth_attempt_log_download_rate_threshold bigint NOT NULL,
auth_attempt_log_upload_quota bigint NOT NULL,
auth_attempt_log_download_quota bigint NOT NULL,
auth_attempt_log_custom_value json
);


Expand Down Expand Up @@ -236,6 +243,55 @@ COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_created_at IS 'create
COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_updated_at IS 'updated timestamp';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_rhid; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_rhid IS 'hashed client hid with gateway password';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_session_length_minutes; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_session_length_minutes IS 'session length minutes';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_upload_rate_threshold; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_upload_rate_threshold IS 'upload rate threshold (KB/s)';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_download_rate_threshold; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_download_rate_threshold IS 'download rate threshold (KB/s)';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_upload_quota; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_upload_quota IS 'upload quota (KB)';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_download_quota; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_download_quota IS 'download quota (KB)';


--
-- Name: COLUMN auth_attempt_log.auth_attempt_log_custom_value; Type: COMMENT; Schema: public; Owner: -
--

COMMENT ON COLUMN public.auth_attempt_log.auth_attempt_log_custom_value IS 'json serialized custom tags';


--
-- Name: gateway; Type: TABLE; Schema: public; Owner: -
--
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/redis/go-redis/v9 v9.1.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.4
github.com/volatiletech/null/v8 v8.1.2
github.com/volatiletech/sqlboiler/v4 v4.15.0
github.com/volatiletech/strmangle v0.0.5
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -25,6 +26,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/friendsofgo/errors v0.9.2 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/klauspost/compress v1.16.3 // indirect
Expand All @@ -36,6 +38,7 @@ require (
github.com/valyala/fasthttp v1.49.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/volatiletech/inflect v0.0.1 // indirect
github.com/volatiletech/randomize v0.0.1 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.10.0 // indirect
Expand Down
83 changes: 83 additions & 0 deletions pkg/auth/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package auth

import (
"encoding/base64"
"fmt"
"net/url"
"strings"
"time"
)

type ClientPolicy struct {
ClientRHID string
SessionDuration time.Duration // Session Duration: minutes
UploadRateThresholdKBs int64 // Upload Rate Limit Threshold: Kb/s
DownloadRateThresholdKBs int64 // Download Rate Limit Threshold: Kb/s
UploadQuotaKB int64 // Upload Quota: KBytes
DownloadQuotaKB int64 // Download Quota: KBytes

Custom map[string]any // Custom values
}

func (c *ClientPolicy) toAuthAttemptLog() {

Check failure on line 22 in pkg/auth/policy.go

View workflow job for this annotation

GitHub Actions / lint

func `(*ClientPolicy).toAuthAttemptLog` is unused (unused)
// TODO: implement
panic("not implemented")
}

// toOpenNDSFormat converts ClientPolicy to the format that is expected by opennds auth daemon ("authmon")
func (c *ClientPolicy) toOpenNDSFormat() string {
custom := ""
if c.Custom != nil && len(c.Custom) > 0 {
idx := 0
kvFormats := make([]string, len(c.Custom))

for k, v := range c.Custom {
kvFormats[idx] = fmt.Sprintf("%s=%s", k, v)
idx += 1
}

custom = strings.Join(kvFormats, ", ")
}

format := fmt.Sprintf(
"%s %d %d %d %d %d %s",
c.ClientRHID,
int64(c.SessionDuration.Minutes()),
c.UploadRateThresholdKBs,
c.DownloadRateThresholdKBs,
c.UploadQuotaKB,
c.DownloadQuotaKB,
base64.StdEncoding.EncodeToString([]byte(custom)),
)

format = url.QueryEscape(format)
// NOTE(@Kcrong): url.QueryEscape replaces spaces with "+", but opennds needs "%20"
format = strings.ReplaceAll(format, "+", "%20")

return format
}

func (c *ClientPolicy) AddTag(key string, value any) {
c.Custom[key] = value
}

func NewClientPolicy(
rhid string,
durationMinutes int64,
uploadRate,
downloadRate,
uploadQuota,
downloadQuota int64,
tags map[string]any,
) *ClientPolicy {

return &ClientPolicy{
ClientRHID: rhid,
SessionDuration: time.Duration(durationMinutes) * time.Minute,
UploadRateThresholdKBs: uploadRate,
DownloadRateThresholdKBs: downloadRate,
UploadQuotaKB: uploadQuota,
DownloadQuotaKB: downloadQuota,
Custom: tags,
}
}
55 changes: 55 additions & 0 deletions pkg/auth/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package auth

import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/pkg/errors"
"github.com/redis/go-redis/v9"
)

// Provider is an interface for client(RHID) authentication
type Provider interface {
ListClients(ctx context.Context, gateway string) ([]string, error)
AddClient(ctx context.Context, gateway, rhid string, policy *ClientPolicy) error
DeleteClient(ctx context.Context, gateway, rhid string) error
}

type provider struct {
redisCli *redis.Client
}

func hash(s string) string {
bs := sha256.Sum256([]byte(s))

return hex.EncodeToString(bs[:])
}

func (p provider) ListClients(ctx context.Context, gateway string) ([]string, error) {
//TODO implement me
panic("implement me")
}

func (p provider) AddClient(ctx context.Context, gateway, rhid string, policy *ClientPolicy) error {
gwHash := hash(gateway)
if err := p.redisCli.LPush(ctx, gwHash, rhid).Err(); err != nil {
return errors.WithStack(err)
}

key := fmt.Sprintf("%s-%s", gwHash, rhid)
if err := p.redisCli.Set(ctx, key, policy.toOpenNDSFormat(), 0).Err(); err != nil {
return errors.WithStack(err)
}

return nil
}

func (p provider) DeleteClient(ctx context.Context, gateway, rhid string) error {
//TODO implement me
panic("implement me")
}

func NewProvider(redisCli *redis.Client) Provider {
return &provider{redisCli: redisCli}
}
Loading

0 comments on commit 2c5c2d0

Please sign in to comment.