Compare commits

..

No commits in common. "main" and "feature/order" have entirely different histories.

29 changed files with 1496 additions and 307 deletions

View File

@ -1,45 +1,32 @@
FROM golang:alpine AS deps
FROM golang:alpine as builder
ARG HOSTNAME=http://localhost
ARG NAME=local
WORKDIR /app
COPY go.mod go.sum ./
RUN sed -i '/replace/d' go.mod
RUN cat go.mod
RUN go mod download
#----------------------------------------------------------------------------------------------
FROM golang:alpine AS builder
RUN apk add git
RUN go install github.com/beego/bee/v2@latest
WORKDIR /oc-auth
COPY --from=deps /go/pkg /go/pkg
COPY --from=deps /app/go.mod /app/go.sum ./
RUN export CGO_ENABLED=0 && \
export GOOS=linux && \
export GOARCH=amd64 && \
export BUILD_FLAGS="-ldflags='-w -s'"
COPY . .
RUN sed -i '/replace/d' go.mod
RUN bee pack
RUN mkdir -p /app/extracted && tar -zxvf oc-auth.tar.gz -C /app/extracted
RUN sed -i 's/http:\/\/127.0.0.1:8080\/swagger\/swagger.json/swagger.json/g' /app/extracted/swagger/index.html
RUN apk add git
#----------------------------------------------------------------------------------------------
RUN go get github.com/beego/bee/v2 && go install github.com/beego/bee/v2@master
FROM golang:alpine
RUN timeout 15 bee run -gendoc=true -downdoc=true -runmode=dev || :
RUN sed -i 's/http:\/\/127.0.0.1:8080\/swagger\/swagger.json/swagger.json/g' swagger/index.html
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" .
RUN ls /app
FROM scratch
WORKDIR /app
COPY --from=builder /app/extracted/oc-auth /usr/bin
COPY --from=builder /app/extracted/swagger /app/swagger
COPY --from=builder /app/extracted/pem /app/pem
COPY --from=builder /app/extracted/docker_auth.json /etc/oc/auth.json
COPY --from=builder /app/oc-auth /usr/bin/
COPY --from=builder /app/swagger /app/swagger
COPY docker_auth.json /etc/oc/auth.json
EXPOSE 8080

View File

@ -1,35 +0,0 @@
.DEFAULT_GOAL := all
build: clean
bee pack
run:
bee run -gendoc=true -downdoc=true
purge:
lsof -t -i:8094 | xargs kill | true
run-dev:
bee generate routers && bee run -gendoc=true -downdoc=true -runmode=prod
dev: purge run-dev
debug:
bee run -downdebug -gendebug
clean:
rm -rf oc-auth oc-auth.tar.gz
docker:
DOCKER_BUILDKIT=1 docker build -t oc/oc-auth:0.0.1 -f Dockerfile .
docker tag oc/oc-auth:0.0.1 oc/oc-auth:latest
publish-kind:
kind load docker-image oc/oc-auth:0.0.1 --name opencloud
publish-registry:
@echo "TODO"
all: docker publish-kind publish-registry
.PHONY: build run clean docker publish-kind publish-registry

View File

@ -7,9 +7,6 @@ To build :
bee generate routers
bee run -gendoc=true -downdoc=true
OR
make dev
If default Swagger page is displayed instead of tyour api, change url in swagger/index.html file to :
url: "swagger.json"

BIN
__debug_bin142225022 Executable file

Binary file not shown.

View File

@ -1,7 +1,9 @@
{
"port": 8080,
"MONGO_URL":"mongodb://localhost:27017/",
"MONGO_DATABASE":"DC_myDC",
"NATS_URL": "nats://localhost:4222",
"LDAP_ENDPOINTS": "localhost:390",
"port": 8094
"natsurl":"http://localhost:4080",
"login":"admin",
"password":"admin",
"oidcserver":"http://localhost:8080"
}

View File

@ -1,5 +1,5 @@
appname = oc-auth
httpport = 8094
httpport = 8080
runmode = dev
autorender = false
copyrequestbody = true

View File

@ -14,22 +14,16 @@ type Config struct {
LDAPBaseDN string
LDAPRoleBaseDN string
ClientSecret string
OAuth2ClientSecretName string
OAuth2ClientSecretNamespace string
ClientSecret string
Auth string
AuthConnectPublicHost string
AuthConnectorHost string
AuthConnectorPort int
AuthConnectorAdminPort int
PermissionConnectorWriteHost string
PermissionConnectorReadHost string
PermissionConnectorHost string
PermissionConnectorPort int
PermissionConnectorAdminPort int
Local bool
}
var instance *Config

View File

@ -8,10 +8,8 @@ import (
"oc-auth/conf"
"oc-auth/infrastructure"
auth_connectors "oc-auth/infrastructure/auth_connector"
"oc-auth/infrastructure/claims"
"regexp"
"strings"
"time"
oclib "cloud.o-forge.io/core/oc-lib"
model "cloud.o-forge.io/core/oc-lib/models/peer"
@ -42,15 +40,11 @@ func (o *OAuthController) LogOut() {
var res auth_connectors.Token
json.Unmarshal(o.Ctx.Input.CopyBody(10000000), &res)
if !conf.GetConfig().Local {
token, err := infrastructure.GetAuthConnector().Logout(clientID, reqToken)
if err != nil || token == nil {
o.Data["json"] = err
} else {
o.Data["json"] = token
}
token, err := infrastructure.GetAuthConnector().Logout(clientID, reqToken)
if err != nil || token == nil {
o.Data["json"] = err
} else {
o.Data["json"] = reqToken
o.Data["json"] = token
}
o.ServeJSON()
}
@ -63,13 +57,14 @@ func (o *OAuthController) LogOut() {
// @router /login [post]
func (o *OAuthController) Login() {
// authorize user
fmt.Println("Login", o.Ctx.Input.Query("client_id"), o.Ctx.Input.Param(":client_id"))
clientID := o.Ctx.Input.Query("client_id")
var res auth_connectors.Token
json.Unmarshal(o.Ctx.Input.CopyBody(10000000), &res)
if conf.GetConfig().SourceMode == "ldap" {
ldap := auth_connectors.New()
found, err := ldap.Authenticate(o.Ctx.Request.Context(), res.Username, res.Password)
fmt.Println("found", found, "err", err)
if err != nil || !found {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
@ -77,44 +72,18 @@ func (o *OAuthController) Login() {
return
}
}
if !conf.GetConfig().Local {
token, err := infrastructure.GetAuthConnector().Login(
clientID, res.Username,
&http.Cookie{ // open a session
Name: "csrf_token",
Value: o.XSRFToken(),
})
if err != nil || token == nil {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
} else {
o.Data["json"] = token
}
token, err := infrastructure.GetAuthConnector().Login(
clientID, res.Username,
&http.Cookie{ // open a session
Name: "csrf_token",
Value: o.XSRFToken(),
})
fmt.Println("token", token, "err", err)
if err != nil || token == nil {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
} else {
t := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).Search(
nil, fmt.Sprintf("%v", model.SELF.EnumIndex()), false)
if t.Err == "" && len(t.Data) > 0 {
token := &auth_connectors.Token{
Username: res.Username,
Password: res.Password,
TokenType: "Bearer",
Active: true,
ExpiresIn: 3600,
AccessToken: "localtoken",
}
now := time.Now().UTC()
now = now.Add(time.Duration(token.ExpiresIn) * time.Second)
unix := now.Unix()
c := claims.GetClaims().AddClaimsToToken(clientID, res.Username, t.Data[0].(*model.Peer))
c.Session.AccessToken["exp"] = unix
b, _ := json.Marshal(c)
token.AccessToken = token.AccessToken + "." + base64.StdEncoding.EncodeToString(b)
o.Data["json"] = token
} else {
o.Data["json"] = t.Err
o.Ctx.ResponseWriter.WriteHeader(401)
}
o.Data["json"] = token
}
o.ServeJSON()
}
@ -130,16 +99,12 @@ func (o *OAuthController) Refresh() {
var token auth_connectors.Token
json.Unmarshal(o.Ctx.Input.CopyBody(100000), &token)
// refresh token
if !conf.GetConfig().Local {
newToken, err := infrastructure.GetAuthConnector().Refresh(clientID, &token)
if err != nil || newToken == nil {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
} else {
o.Data["json"] = newToken
}
newToken, err := infrastructure.GetAuthConnector().Refresh(clientID, &token)
if err != nil || newToken == nil {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
} else {
o.Data["json"] = token
o.Data["json"] = newToken
}
o.ServeJSON()
}
@ -157,12 +122,11 @@ func (o *OAuthController) Introspect() {
} else {
reqToken = splitToken[1]
}
if !conf.GetConfig().Local {
token, err := infrastructure.GetAuthConnector().Introspect(reqToken)
if err != nil || !token {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
}
token, err := infrastructure.GetAuthConnector().Introspect(reqToken)
if err != nil || !token {
o.Data["json"] = err
o.Ctx.ResponseWriter.WriteHeader(401)
}
o.ServeJSON()
}
@ -178,7 +142,7 @@ var whitelist = []string{
// @Param Authorization header string false "auth token"
// @Success 200 {string}
// @router /forward [get]
func (o *OAuthController) InternalAuthForward() {
func (o *OAuthController) InternaisDraftlAuthForward() {
fmt.Println("InternalAuthForward")
reqToken := o.Ctx.Request.Header.Get("Authorization")
if reqToken == "" {

View File

@ -14,10 +14,7 @@ type VersionController struct {
// @Success 200
// @router / [get]
func (c *VersionController) GetAll() {
c.Data["json"] = map[string]string{
"service": "oc-auth",
"version": "1",
}
c.Data["json"] = map[string]string{"version": "1"}
c.ServeJSON()
}
@ -26,9 +23,6 @@ func (c *VersionController) GetAll() {
// @Success 200
// @router /discovery [get]
func (c *VersionController) Get() {
c.Data["json"] = map[string]string{
"service": "oc-auth",
"version": "1",
}
c.Data["json"] = map[string]string{"version": "1"}
c.ServeJSON()
}

21
docker-compose-2.yml Normal file
View File

@ -0,0 +1,21 @@
version: '3.4'
services:
oc-auth-2:
image: 'oc-auth-2:latest'
ports:
- 8095:8080
container_name: oc-auth-2
environment:
LDAP_ENDPOINTS: ldap-2:389
LDAP_BINDDN: cn=admin,dc=example,dc=com
LDAP_BINDPW: password
LDAP_BASEDN: "dc=example,dc=com"
LDAP_ROLE_BASEDN: "ou=AppRoles,dc=example,dc=com"
networks:
- catalog
volumes:
- ./pem:/etc/oc/pem
networks:
catalog:
external: true

View File

@ -1,6 +1,22 @@
version: '3.4'
services:
traefik:
image: traefik:v2.10.4
container_name: traefik
networks:
- catalog
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--log.level=DEBUG"
ports:
- "8080:80"
- "8082:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
oc-auth:
image: 'oc-auth:latest'
ports:
@ -8,13 +24,8 @@ services:
container_name: oc-auth
labels:
- "traefik.enable=true"
- "traefik.http.routers.auth.entrypoints=web"
- "traefik.http.routers.auth.rule=PathPrefix(`/auth`)"
- "traefik.http.middlewares.auth-rewrite.replacepathregex.regex=^/auth(.*)"
- "traefik.http.middlewares.auth-rewrite.replacepathregex.replacement=/oc$$1"
- "traefik.http.routers.auth.middlewares=auth-rewrite"
- "traefik.http.services.auth.loadbalancer.server.port=8080"
- "traefik.http.middlewares.auth.forwardauth.address=http://oc-auth:8080/oc/forward"
- "traefik.http.routers.workflow.rule=PathPrefix(/auth)"
environment:
LDAP_ENDPOINTS: ldap:389
LDAP_BINDDN: cn=admin,dc=example,dc=com
@ -22,10 +33,9 @@ services:
LDAP_BASEDN: "dc=example,dc=com"
LDAP_ROLE_BASEDN: "ou=AppRoles,dc=example,dc=com"
networks:
- oc
- catalog
volumes:
- ./pem/private.pem:/keys/private/private.pem
- ./pem/public.pem:/keys/public/public.pem
- ./pem:/etc/oc/pem
networks:
oc:
catalog:
external: true

View File

@ -2,10 +2,9 @@
"MONGO_URL":"mongodb://mongo:27017/",
"MONGO_DATABASE":"DC_myDC",
"NATS_URL": "nats://nats:4222",
"PORT" : 8080,
"AUTH_CONNECTOR_HOST": "hydra",
"AUTH_CONNECTOR_PUBLIC_HOST": "hydra",
"PRIVATE_KEY_PATH": "/keys/private/private.pem",
"PUBLIC_KEY_PATH": "/keys/public/public.pem",
"LDAP_ENDPOINTS": "ldap:389",
"LOCAL": false
"PRIVATE_KEY_PATH": "/etc/oc/pem/private.pem",
"PUBLIC_KEY_PATH": "/etc/oc/pem/public.pem",
"LDAP_ENDPOINTS": "ldap:389"
}

84
go.mod
View File

@ -1,29 +1,85 @@
module oc-auth
go 1.23.0
toolchain go1.23.3
go 1.22.0
require (
cloud.o-forge.io/core/oc-lib v0.0.0-20250219142942-5111c9c8bec7
cloud.o-forge.io/core/oc-lib v0.0.0-20250211081618-d82ae166a1e5
github.com/beego/beego/v2 v2.3.1
github.com/nats-io/nats.go v1.37.0
github.com/ory/hydra-client-go v1.11.8
github.com/smartystreets/goconvey v1.7.2
go.uber.org/zap v1.27.0
golang.org/x/oauth2 v0.23.0
)
//replace cloud.o-forge.io/core/oc-lib => ../oc-lib
require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/biter777/countries v1.7.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gobuffalo/pop/v6 v6.0.8 // indirect
github.com/gofrs/uuid v4.3.0+incompatible // indirect
github.com/nats-io/nats.go v1.37.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/marcinwyszynski/geopoint v0.0.0-20140302213024-cf2a6f750c5b // indirect
github.com/mattn/goveralls v0.0.12 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/openzipkin/zipkin-go v0.4.1 // indirect
github.com/ory/go-acc v0.2.9-0.20230103102148-6b1c9a70dbbe // indirect
github.com/ory/go-convenience v0.1.0 // indirect
github.com/ory/x v0.0.575 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/robfig/cron v1.2.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/seatgeek/logrus-gelf-formatter v0.0.0-20210414080842-5b05eb8ff761 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.16.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.42.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect
go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect
go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
go.opentelemetry.io/contrib/samplers/jaegerremote v0.11.0 // indirect
go.opentelemetry.io/otel v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.16.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/sdk v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.63.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
require (
@ -35,6 +91,7 @@ require (
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.22.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
@ -42,7 +99,10 @@ require (
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/i-core/rlog v1.0.0
github.com/jtolds/gls v4.20.0+incompatible // indirect
github.com/justinas/nosurf v1.1.1
github.com/kelseyhightower/envconfig v1.4.0
github.com/klauspost/compress v1.17.11 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@ -51,10 +111,13 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/ory/fosite v0.47.0
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.60.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/purnaresa/bulwark v0.0.0-20201001150757-1cec324746b2
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
@ -68,6 +131,7 @@ require (
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/text v0.19.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

1060
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ package auth_connectors
import (
"net/http"
"oc-auth/conf"
"strings"
"cloud.o-forge.io/core/oc-lib/tools"
)
@ -38,10 +37,5 @@ var a = map[string]AuthConnector{
}
func GetAuthConnector() AuthConnector {
for k := range a {
if strings.Contains(conf.GetConfig().Auth, k) {
return a[k]
}
}
return nil
return a[conf.GetConfig().Auth]
}

View File

@ -32,9 +32,6 @@ func (a HydraConnector) Status() tools.State {
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
var responseBody map[string]interface{}
host := conf.GetConfig().AuthConnectorHost
if conf.GetConfig().Local {
host = "localhost"
}
port := fmt.Sprintf("%v", conf.GetConfig().AuthConnectorPort)
resp, err := caller.CallGet("http://"+host+":"+port, "/health/ready")
if err != nil {
@ -71,7 +68,6 @@ func (a HydraConnector) challenge(username string, url string, challenge string,
resp, err := a.Caller.CallRaw(http.MethodPut,
a.getPath(true, true), "/auth/requests/"+challenge+"/accept?"+challenge+"_challenge="+s[1],
body, "application/json", true, cookies...) // "remember": true, "subject": username
fmt.Println(a.getPath(true, true), "/auth/requests/"+challenge+"/accept?"+challenge+"_challenge="+s[1], resp, err)
if err != nil {
return nil, s[1], cookies, err
}
@ -142,11 +138,11 @@ func (a HydraConnector) getClient(clientID string) string {
}
func (a HydraConnector) Login(clientID string, username string, cookies ...*http.Cookie) (t *Token, err error) {
fmt.Println("login", clientID, username)
clientID = a.getClient(clientID)
redirect, _, cookies, err := a.tryLog(username, a.getPath(false, true),
"/auth?client_id="+clientID+"&response_type="+strings.ReplaceAll(a.ResponseType, " ", "%20")+"&scope="+strings.ReplaceAll(a.Scopes, " ", "%20")+"&state="+a.State,
"login", cookies...)
fmt.Println("login", clientID, username, a.getPath(false, true), redirect, err)
if err != nil || redirect == nil {
return nil, err
}
@ -194,6 +190,7 @@ func (a HydraConnector) Login(clientID string, username string, cookies ...*http
unix := now.Unix()
c := claims.GetClaims().AddClaimsToToken(clientID, username, pp.Data[0].(*peer.Peer))
fmt.Println("claims", c.Session.AccessToken)
c.Session.AccessToken["exp"] = unix
b, _ = json.Marshal(c)
@ -253,9 +250,6 @@ func (a HydraConnector) Introspect(token string, cookie ...*http.Cookie) (bool,
func (a HydraConnector) getPath(isAdmin bool, isOauth bool) string {
host := conf.GetConfig().AuthConnectorHost
if conf.GetConfig().Local {
host = "localhost"
}
port := fmt.Sprintf("%v", conf.GetConfig().AuthConnectorPort)
if isAdmin {
port = fmt.Sprintf("%v", conf.GetConfig().AuthConnectorAdminPort) + "/admin"

View File

@ -228,7 +228,7 @@ func (cli *Client) FindOIDCClaims(ctx context.Context, username string) ([]LDAPC
// It's sufficient to compare the DN's suffix with the base DN.
n, k := len(roleDN), len(cli.RoleBaseDN)
if n < k || !strings.EqualFold(roleDN[n-k:], cli.RoleBaseDN) {
return nil, errors.New("You should never see that")
panic("You should never see that")
}
// The DN without the role's base DN must contain a CN and OU
// where the CN is for uniqueness only, and the OU is an application id.
@ -322,7 +322,7 @@ func (cli *Client) findRoles(cn conn, attrs ...string) (map[string]LDAPRoles, er
// It's sufficient to compare the DN's suffix with the base DN.
n, k := len(roleDN), len(cli.RoleBaseDN)
if n < k || !strings.EqualFold(roleDN[n-k:], cli.RoleBaseDN) {
return nil, errors.New("You should never see that")
panic("You should never see that")
}
// The DN without the role's base DN must contain a CN and OU
// where the CN is for uniqueness only, and the OU is an application id.

View File

@ -2,7 +2,6 @@ package claims
import (
"oc-auth/conf"
"strings"
"cloud.o-forge.io/core/oc-lib/models/peer"
)
@ -29,10 +28,5 @@ var t = map[string]ClaimService{
}
func GetClaims() ClaimService {
for k := range t {
if strings.Contains(conf.GetConfig().Auth, k) {
return t[k]
}
}
return nil
return t[conf.GetConfig().Auth]
}

View File

@ -56,10 +56,7 @@ func (f KetoConnector) permToQuery(perm Permission, permDependancies *Permission
func (k KetoConnector) Status() tools.State {
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
var responseBody map[string]interface{}
host := conf.GetConfig().PermissionConnectorReadHost
if conf.GetConfig().Local {
host = "localhost"
}
host := conf.GetConfig().PermissionConnectorHost
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorPort)
resp, err := caller.CallGet("http://"+host+":"+port, "/health/ready")
if err != nil {
@ -81,7 +78,7 @@ func (k KetoConnector) CheckPermission(perm Permission, permDependancies *Permis
perms, err := k.GetPermission(perm.Object, perm.Relation)
if err != nil {
log := oclib.GetLogger()
log.Error().Msg("CheckPermission " + err.Error())
log.Error().Msg(err.Error())
return false
}
return len(perms) > 0
@ -220,10 +217,7 @@ func (k KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Perm
func (k KetoConnector) get(object string, relation string, subject string) ([]Permission, error) {
t := []Permission{}
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
host := conf.GetConfig().PermissionConnectorReadHost
if conf.GetConfig().Local {
host = "localhost"
}
host := conf.GetConfig().PermissionConnectorHost
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorPort)
resp, err := caller.CallGet("http://"+host+":"+port, "/relation-tuples"+k.permToQuery(
Permission{Object: object, Relation: relation, Subject: subject}, nil))
@ -350,23 +344,19 @@ func (k KetoConnector) createRelationShip(object string, relation string, subjec
}
body["subject_set"] = map[string]interface{}{"namespace": k.namespace(), "object": s.Object, "relation": s.Relation, "subject_id": s.Subject}
}
host := conf.GetConfig().PermissionConnectorWriteHost
if conf.GetConfig().Local {
host = "localhost"
}
host := conf.GetConfig().PermissionConnectorHost
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort)
b, err := caller.CallPut("http://"+host+":"+port, "/relation-tuples", body)
if err != nil {
log := oclib.GetLogger()
log.Error().Msg("createRelationShip" + err.Error())
log.Error().Msg(err.Error())
return nil, 500, err
}
var data map[string]interface{}
err = json.Unmarshal(b, &data)
if err != nil {
fmt.Println(string(b), err)
log := oclib.GetLogger()
log.Error().Msg("createRelationShip2" + err.Error())
log.Error().Msg(err.Error())
return nil, 500, err
}
perm := &Permission{
@ -392,15 +382,12 @@ func (k KetoConnector) deleteRelationShip(object string, relation string, subjec
}
caller := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{})
n := k.permToQuery(Permission{Object: object, Relation: relation, Subject: subject}, subPerm)
host := conf.GetConfig().PermissionConnectorWriteHost
if conf.GetConfig().Local {
host = "localhost"
}
host := conf.GetConfig().PermissionConnectorHost
port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort)
b, err := caller.CallDelete("http://"+host+":"+port, "/relation-tuples"+n)
if err != nil {
log := oclib.GetLogger()
log.Error().Msg("deleteRelationShip " + err.Error())
log.Error().Msg(err.Error())
return nil, 500, err
}
var data map[string]interface{}

View File

@ -2,7 +2,6 @@ package perms_connectors
import (
"oc-auth/conf"
"strings"
"cloud.o-forge.io/core/oc-lib/tools"
)
@ -56,10 +55,5 @@ var c = map[string]PermConnector{
}
func GetPermissionConnector(scope string) PermConnector {
for k := range c {
if strings.Contains(conf.GetConfig().PermissionConnectorReadHost, k) {
return c[k]
}
}
return nil
return c[conf.GetConfig().PermissionConnectorHost]
}

21
keto/docker-compose.yml Normal file
View File

@ -0,0 +1,21 @@
version: '3.4'
services:
keto:
image: oryd/keto:v0.7.0-alpha.1-sqlite
ports:
- "4466:4466"
- "4467:4467"
command: serve -c /home/ory/keto.yml
restart: on-failure
volumes:
- type: bind
source: .
target: /home/ory
container_name: keto
networks:
- catalog
networks:
catalog:
external: true

18
keto/keto.yml Normal file
View File

@ -0,0 +1,18 @@
version: v0.6.0-alpha.1
log:
level: debug
namespaces:
- id: 0
name: open-cloud
dsn: memory
serve:
read:
host: 0.0.0.0
port: 4466
write:
host: 0.0.0.0
port: 4467

View File

@ -0,0 +1,78 @@
version: "3"
services:
hydra-client-2:
image: oryd/hydra:v2.2.0
container_name: hydra-client-2
environment:
HYDRA_ADMIN_URL: http://hydra-2:4445
ORY_SDK_URL: http://hydra-2:4445
command:
- create
- oauth2-client
- --skip-tls-verify
- --name
- test-client
- --secret
- oc-auth-got-secret
- --response-type
- id_token,token,code
- --grant-type
- implicit,refresh_token,authorization_code,client_credentials
- --scope
- openid,profile,email,roles
- --token-endpoint-auth-method
- client_secret_post
- --redirect-uri
- http://localhost:3000
networks:
- hydra-net
- catalog
deploy:
restart_policy:
condition: none
depends_on:
- hydra-2
healthcheck:
test: ["CMD", "curl", "-f", "http://hydra-2:4445"]
interval: 10s
timeout: 10s
retries: 10
hydra-2:
container_name: hydra-2
image: oryd/hydra:v2.2.0
environment:
SECRETS_SYSTEM: oc-auth-got-secret
LOG_LEAK_SENSITIVE_VALUES: true
URLS_SELF_ISSUER: http://hydra-2:4444
URLS_SELF_PUBLIC: http://hydra-2:4444
WEBFINGER_OIDC_DISCOVERY_SUPPORTED_SCOPES: profile,email,phone,roles
WEBFINGER_OIDC_DISCOVERY_SUPPORTED_CLAIMS: name,family_name,given_name,nickname,email,phone_number
DSN: memory
command: serve all --dev
networks:
- hydra-net
- catalog
ports:
- "4446:4444"
- "4447:4445"
deploy:
restart_policy:
condition: on-failure
ldap-2:
image: pgarrett/ldap-alpine
container_name: ldap-2
volumes:
- "./ldap-2.ldif:/ldif/ldap.ldif"
networks:
- hydra-net
- catalog
ports:
- "389:389"
deploy:
restart_policy:
condition: on-failure
networks:
hydra-net:
catalog:
external: true

View File

@ -0,0 +1,79 @@
version: "3"
services:
hydra-client:
image: oryd/hydra:v2.2.0
container_name: hydra-client
environment:
HYDRA_ADMIN_URL: http://hydra:4445
ORY_SDK_URL: http://hydra:4445
command:
- create
- oauth2-client
- --skip-tls-verify
- --name
- test-client
- --secret
- oc-auth-got-secret
- --response-type
- id_token,token,code
- --grant-type
- implicit,refresh_token,authorization_code,client_credentials
- --scope
- openid,profile,email,roles
- --token-endpoint-auth-method
- client_secret_post
- --redirect-uri
- http://localhost:3000
networks:
- hydra-net
- catalog
deploy:
restart_policy:
condition: none
depends_on:
- hydra
healthcheck:
test: ["CMD", "curl", "-f", "http://hydra:4445"]
interval: 10s
timeout: 10s
retries: 10
hydra:
container_name: hydra
image: oryd/hydra:v2.2.0
environment:
SECRETS_SYSTEM: oc-auth-got-secret
LOG_LEAK_SENSITIVE_VALUES: true
# OAUTH2_TOKEN_HOOK_URL: http://oc-auth:8080/oc/claims
URLS_SELF_ISSUER: http://hydra:4444
URLS_SELF_PUBLIC: http://hydra:4444
WEBFINGER_OIDC_DISCOVERY_SUPPORTED_SCOPES: profile,email,phone,roles
WEBFINGER_OIDC_DISCOVERY_SUPPORTED_CLAIMS: name,family_name,given_name,nickname,email,phone_number
DSN: memory
command: serve all --dev
networks:
- hydra-net
- catalog
ports:
- "4444:4444"
- "4445:4445"
deploy:
restart_policy:
condition: on-failure
ldap:
image: pgarrett/ldap-alpine
container_name: ldap
volumes:
- "./ldap.ldif:/ldif/ldap.ldif"
networks:
- hydra-net
- catalog
ports:
- "390:389"
deploy:
restart_policy:
condition: on-failure
networks:
hydra-net:
catalog:
external: true

24
ldap-hydra/ldap-2.ldif Normal file
View File

@ -0,0 +1,24 @@
dn: uid=admin2,ou=Users,dc=example,dc=com
objectClass: inetOrgPerson
cn: Admin2
sn: Istrator
uid: admin2
userPassword: admin2
mail: admin2@example.com
ou: Users
dn: ou=AppRoles,dc=example,dc=com
objectClass: organizationalunit
ou: AppRoles
description: AppRoles
dn: ou=App1,ou=AppRoles,dc=example,dc=com
objectClass: organizationalunit
ou: App1
description: App1
dn: cn=traveler,ou=App1,ou=AppRoles,dc=example,dc=com
objectClass: groupofnames
cn: traveler
description: traveler
member: uid=admin2,ou=Users,dc=example,dc=com

24
ldap-hydra/ldap.ldif Normal file
View File

@ -0,0 +1,24 @@
dn: uid=admin,ou=Users,dc=example,dc=com
objectClass: inetOrgPerson
cn: Admin
sn: Istrator
uid: admin
userPassword: admin
mail: admin@example.com
ou: Users
dn: ou=AppRoles,dc=example,dc=com
objectClass: organizationalunit
ou: AppRoles
description: AppRoles
dn: ou=App1,ou=AppRoles,dc=example,dc=com
objectClass: organizationalunit
ou: App1
description: App1
dn: cn=traveler,ou=App1,ou=AppRoles,dc=example,dc=com
objectClass: groupofnames
cn: traveler
description: traveler
member: uid=admin,ou=Users,dc=example,dc=com

73
main.go
View File

@ -11,14 +11,12 @@ import (
"os"
"strconv"
"strings"
"time"
oclib "cloud.o-forge.io/core/oc-lib"
peer "cloud.o-forge.io/core/oc-lib/models/peer"
"cloud.o-forge.io/core/oc-lib/models/utils"
"cloud.o-forge.io/core/oc-lib/tools"
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/server/web/filter/cors"
)
const appname = "oc-auth"
@ -37,18 +35,14 @@ func main() {
conf.GetConfig().PublicKeyPath = o.GetStringDefault("PUBLIC_KEY_PATH", "./pem/public.pem")
conf.GetConfig().PrivateKeyPath = o.GetStringDefault("PRIVATE_KEY_PATH", "./pem/private.pem")
conf.GetConfig().ClientSecret = o.GetStringDefault("CLIENT_SECRET", "oc-auth-got-secret")
conf.GetConfig().OAuth2ClientSecretName = o.GetStringDefault("OAUTH2_CLIENT_SECRET_NAME", "oc-oauth2-client-secret")
conf.GetConfig().OAuth2ClientSecretNamespace = o.GetStringDefault("NAMESPACE", "default")
conf.GetConfig().Auth = o.GetStringDefault("AUTH", "hydra")
conf.GetConfig().AuthConnectorHost = o.GetStringDefault("AUTH_CONNECTOR_HOST", "localhost")
conf.GetConfig().AuthConnectPublicHost = o.GetStringDefault("AUTH_CONNECTOR_PUBLIC_HOST", "localhost")
conf.GetConfig().AuthConnectorPort = o.GetIntDefault("AUTH_CONNECTOR_PORT", 4444)
conf.GetConfig().AuthConnectorAdminPort = o.GetIntDefault("AUTH_CONNECTOR_ADMIN_PORT", 4445)
conf.GetConfig().PermissionConnectorWriteHost = o.GetStringDefault("PERMISSION_CONNECTOR_WRITE_HOST", "keto")
conf.GetConfig().PermissionConnectorReadHost = o.GetStringDefault("PERMISSION_CONNECTOR_READ_HOST", "keto")
conf.GetConfig().PermissionConnectorHost = o.GetStringDefault("PERMISSION_CONNECTOR_HOST", "keto")
conf.GetConfig().PermissionConnectorPort = o.GetIntDefault("PERMISSION_CONNECTOR_PORT", 4466)
conf.GetConfig().PermissionConnectorAdminPort = o.GetIntDefault("PERMISSION_CONNECTOR_ADMIN_PORT", 4467)
conf.GetConfig().Local = o.GetBoolDefault("LOCAL", true)
// config LDAP
conf.GetConfig().SourceMode = o.GetStringDefault("SOURCE_MODE", "ldap")
@ -57,17 +51,12 @@ func main() {
conf.GetConfig().LDAPBindPW = o.GetStringDefault("LDAP_BINDPW", "password")
conf.GetConfig().LDAPBaseDN = o.GetStringDefault("LDAP_BASEDN", "dc=example,dc=com")
conf.GetConfig().LDAPRoleBaseDN = o.GetStringDefault("LDAP_ROLE_BASEDN", "ou=AppRoles,dc=example,dc=com")
go generateSelfPeer()
go generateRole()
go discovery()
beego.BConfig.Listen.HTTPPort = o.GetIntDefault("port", 8080)
beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
AllowAllOrigins: true,
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowHeaders: []string{"Origin", "Authorization", "Content-Type"},
ExposeHeaders: []string{"Content-Length", "Content-Type"},
AllowCredentials: true,
}))
err := generateSelfPeer()
if err != nil {
panic(err)
}
generateRole()
discovery()
beego.Run()
}
@ -81,29 +70,22 @@ func generateRole() {
if conf.GetConfig().SourceMode == "ldap" {
ldap := auth_connectors.New()
roles, err := ldap.GetRoles(context.Background())
if err == nil {
fmt.Println("ROLE", roles)
for _, role := range roles {
for r, m := range role.Members {
infrastructure.GetPermissionConnector("").CreateRole(r)
for _, p := range m {
infrastructure.GetPermissionConnector("").BindRole(r, p)
}
if err != nil {
panic(err)
}
fmt.Println("ROLE", roles)
for _, role := range roles {
for r, m := range role.Members {
infrastructure.GetPermissionConnector("").CreateRole(r)
for _, p := range m {
infrastructure.GetPermissionConnector("").BindRole(r, p)
}
}
} else {
time.Sleep(10 * time.Second) // Pause execution for 10 seconds
generateRole()
}
}
}
func generateSelfPeer() error {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
// TODO check if files at private & public path are set
// check if files at private & public path are set
if _, err := os.Stat(conf.GetConfig().PrivateKeyPath); errors.Is(err, os.ErrNotExist) {
@ -135,34 +117,21 @@ func generateSelfPeer() error {
AbstractObject: utils.AbstractObject{
Name: o.GetStringDefault("NAME", "local"),
},
PublicKey: file,
State: peer.SELF,
WalletAddress: "my-wallet",
PublicKey: file,
State: peer.SELF,
}
data := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).StoreOne(peer.Serialize(peer))
if data.Err != "" {
time.Sleep(10 * time.Second) // Pause execution for 10 seconds
generateSelfPeer()
return errors.New(data.Err)
}
return nil
}
func discovery() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
api := tools.API{}
conn := infrastructure.GetPermissionConnector("")
fmt.Println("AdminRole", conn, conf.GetConfig().PermissionConnectorWriteHost)
_, _, err := conn.CreateRole(conf.GetConfig().AdminRole)
if err != nil {
time.Sleep(10 * time.Second) // Pause execution for 10 seconds
discovery()
return
}
conn.CreateRole(conf.GetConfig().AdminRole)
conn.BindRole(conf.GetConfig().AdminRole, "admin")
addPermissions := func(m map[string]interface{}) {
for k, v := range m {

BIN
oc-auth

Binary file not shown.

View File

@ -81,7 +81,7 @@ func init() {
beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"] = append(beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"],
beego.ControllerComments{
Method: "InternalAuthForward",
Method: "InternaisDraftlAuthForward",
Router: `/forward`,
AllowHTTPMethods: []string{"get"},
MethodParams: param.Make(),