diff --git a/conf/config.go b/conf/config.go index 7f56f50..19ca87b 100644 --- a/conf/config.go +++ b/conf/config.go @@ -3,6 +3,7 @@ package conf import "sync" type Config struct { + SourceMode string AdminRole string PublicKeyPath string PrivateKeyPath string diff --git a/controllers/group.go b/controllers/group.go index d41040f..08a4947 100644 --- a/controllers/group.go +++ b/controllers/group.go @@ -19,7 +19,8 @@ type GroupController struct { func (o *GroupController) Post() { // store and return Id or post with UUID id := o.Ctx.Input.Param(":id") - group, code, err := infrastructure.GetPermissionConnector().CreateGroup(id) + clientID := ExtractClient(*o.Ctx.Request) + group, code, err := infrastructure.GetPermissionConnector(clientID).CreateGroup(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -44,7 +45,8 @@ func (o *GroupController) Post() { // @router /user/:id [get] func (o *GroupController) GetByUser() { id := o.Ctx.Input.Param(":id") - group, err := infrastructure.GetPermissionConnector().GetGroupByUser(id) + clientID := ExtractClient(*o.Ctx.Request) + group, err := infrastructure.GetPermissionConnector(clientID).GetGroupByUser(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -67,7 +69,8 @@ func (o *GroupController) GetByUser() { // @Success 200 {group} string // @router / [get] func (o *GroupController) GetAll() { - group, err := infrastructure.GetPermissionConnector().GetGroup("") + clientID := ExtractClient(*o.Ctx.Request) + group, err := infrastructure.GetPermissionConnector(clientID).GetGroup("") if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -92,7 +95,8 @@ func (o *GroupController) GetAll() { // @router /:id [get] func (o *GroupController) Get() { id := o.Ctx.Input.Param(":id") - group, err := infrastructure.GetPermissionConnector().GetGroup(id) + clientID := ExtractClient(*o.Ctx.Request) + group, err := infrastructure.GetPermissionConnector(clientID).GetGroup(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -117,7 +121,8 @@ func (o *GroupController) Get() { // @router /:id [delete] func (o *GroupController) Delete() { id := o.Ctx.Input.Param(":id") - group, code, err := infrastructure.GetPermissionConnector().DeleteGroup(id) + clientID := ExtractClient(*o.Ctx.Request) + group, code, err := infrastructure.GetPermissionConnector(clientID).DeleteGroup(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -140,7 +145,8 @@ func (o *GroupController) Delete() { // @Success 200 {string} delete success! // @router /clear [delete] func (o *GroupController) Clear() { - group, code, err := infrastructure.GetPermissionConnector().DeleteGroup("") + clientID := ExtractClient(*o.Ctx.Request) + group, code, err := infrastructure.GetPermissionConnector(clientID).DeleteGroup("") if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -167,7 +173,8 @@ func (o *GroupController) Clear() { func (o *GroupController) Bind() { user_id := o.Ctx.Input.Param(":user_id") group_id := o.Ctx.Input.Param(":group_id") - group, code, err := infrastructure.GetPermissionConnector().BindGroup(user_id, group_id) + clientID := ExtractClient(*o.Ctx.Request) + group, code, err := infrastructure.GetPermissionConnector(clientID).BindGroup(user_id, group_id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -187,14 +194,15 @@ func (o *GroupController) Bind() { // @Title UnBind // @Description unbind the group to user -// @Param group_id path string true "The group_id you want to unbind" +// @Param user_id path string true "The group_id you want to unbind" // @Param group_id path string true "The user_id you want to unbind" // @Success 200 {string} bind success! // @router /:user_id/:group_id [delete] func (o *GroupController) UnBind() { user_id := o.Ctx.Input.Param(":user_id") group_id := o.Ctx.Input.Param(":group_id") - group, code, err := infrastructure.GetPermissionConnector().UnBindGroup(user_id, group_id) + clientID := ExtractClient(*o.Ctx.Request) + group, code, err := infrastructure.GetPermissionConnector(clientID).UnBindGroup(user_id, group_id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, diff --git a/controllers/oauth2.go b/controllers/oauth2.go index ea90d8a..1acc7fb 100644 --- a/controllers/oauth2.go +++ b/controllers/oauth2.go @@ -1,9 +1,11 @@ package controllers import ( + "encoding/base64" "encoding/json" "fmt" "net/http" + "oc-auth/conf" "oc-auth/infrastructure" auth_connectors "oc-auth/infrastructure/auth_connector" "regexp" @@ -22,10 +24,12 @@ type OAuthController struct { // @Title Logout // @Description unauthenticate user // @Param Authorization header string false "auth token" +// @Param client_id query string true "the client_id you want to get" // @Success 200 {string} -// @router /ldap/logout [delete] -func (o *OAuthController) LogOutLDAP() { +// @router /logout [delete] +func (o *OAuthController) LogOut() { // authorize user + clientID := o.Ctx.Input.Query("client_id") reqToken := o.Ctx.Request.Header.Get("Authorization") splitToken := strings.Split(reqToken, "Bearer ") if len(splitToken) < 2 { @@ -36,7 +40,7 @@ func (o *OAuthController) LogOutLDAP() { var res auth_connectors.Token json.Unmarshal(o.Ctx.Input.CopyBody(10000000), &res) - token, err := infrastructure.GetAuthConnector().Logout(reqToken) + token, err := infrastructure.GetAuthConnector().Logout(clientID, reqToken) if err != nil || token == nil { o.Data["json"] = err } else { @@ -48,25 +52,33 @@ func (o *OAuthController) LogOutLDAP() { // @Title Login // @Description authenticate user // @Param body body models.workflow true "The workflow content" +// @Param client_id query string true "the client_id you want to get" // @Success 200 {string} -// @router /ldap/login [post] -func (o *OAuthController) LoginLDAP() { +// @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) - ldap := auth_connectors.New() - found, err := ldap.Authenticate(o.Ctx.Request.Context(), res.Username, res.Password) - if err != nil || !found { - o.Data["json"] = err - o.Ctx.ResponseWriter.WriteHeader(401) - o.ServeJSON() - return + 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) + o.ServeJSON() + return + } } - token, err := infrastructure.GetAuthConnector().Login(res.Username, + 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) @@ -79,13 +91,15 @@ func (o *OAuthController) LoginLDAP() { // @Title Introspection // @Description introspect token // @Param body body models.Token true "The token info" +// @Param client_id query string true "the client_id you want to get" // @Success 200 {string} // @router /refresh [post] func (o *OAuthController) Refresh() { + clientID := o.Ctx.Input.Query("client_id") var token auth_connectors.Token json.Unmarshal(o.Ctx.Input.CopyBody(100000), &token) // refresh token - newToken, err := infrastructure.GetAuthConnector().Refresh(&token) + newToken, err := infrastructure.GetAuthConnector().Refresh(clientID, &token) if err != nil || newToken == nil { o.Data["json"] = err o.Ctx.ResponseWriter.WriteHeader(401) @@ -128,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 == "" { @@ -149,7 +163,7 @@ func (o *OAuthController) InternalAuthForward() { } else { reqToken = splitToken[1] } - origin, publicKey, external := o.extractOrigin() + origin, publicKey, external := o.extractOrigin(o.Ctx.Request) if !infrastructure.GetAuthConnector().CheckAuthForward( //reqToken != "" && reqToken, publicKey, origin, o.Ctx.Request.Header.Get("X-Forwarded-Method"), @@ -161,7 +175,8 @@ func (o *OAuthController) InternalAuthForward() { o.ServeJSON() } -func (o *OAuthController) extractOrigin() (string, string, bool) { +func (o *OAuthController) extractOrigin(request *http.Request) (string, string, bool) { + user, peerID, groups := oclib.ExtractTokenInfo(*request) external := true publicKey := "" origin := o.Ctx.Request.Header.Get("X-Forwarded-Host") @@ -174,7 +189,7 @@ func (o *OAuthController) extractOrigin() (string, string, bool) { if t != "" { searchStr = strings.Replace(searchStr, t, "", -1) } - peer := oclib.Search(nil, searchStr, oclib.LibDataEnum(oclib.PEER)) + peer := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).Search(nil, searchStr, false) if peer.Code != 200 || len(peer.Data) == 0 { // TODO: add state of partnership return "", "", external } @@ -190,3 +205,29 @@ func (o *OAuthController) extractOrigin() (string, string, bool) { } return origin, publicKey, external } + +func ExtractClient(request http.Request) string { + reqToken := request.Header.Get("Authorization") + splitToken := strings.Split(reqToken, "Bearer ") + if len(splitToken) < 2 { + reqToken = "" + } else { + reqToken = splitToken[1] + } + if reqToken != "" { + token := strings.Split(reqToken, ".") + if len(token) > 2 { + bytes, err := base64.StdEncoding.DecodeString(token[2]) + if err != nil { + return "" + } + m := map[string]interface{}{} + err = json.Unmarshal(bytes, &m) + if err != nil { + return "" + } + return m["session"].(map[string]interface{})["id_token"].(map[string]interface{})["client_id"].(string) + } + } + return "" +} diff --git a/controllers/permission.go b/controllers/permission.go index a51d763..678f2bb 100644 --- a/controllers/permission.go +++ b/controllers/permission.go @@ -16,7 +16,8 @@ type PermissionController struct { // @Success 200 {permission} string // @router / [get] func (o *PermissionController) GetAll() { - role, err := infrastructure.GetPermissionConnector().GetPermission("", "") + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetPermission("", "") if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -41,7 +42,8 @@ func (o *PermissionController) GetAll() { // @router /role/:id [get] func (o *PermissionController) GetByRole() { id := o.Ctx.Input.Param(":id") - role, err := infrastructure.GetPermissionConnector().GetPermissionByRole(id) + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetPermissionByRole(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -66,7 +68,8 @@ func (o *PermissionController) GetByRole() { // @router /user/:id [get] func (o *PermissionController) GetByUser() { id := o.Ctx.Input.Param(":id") - role, err := infrastructure.GetPermissionConnector().GetPermissionByUser(id, true) + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetPermissionByUser(id, true) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -92,7 +95,8 @@ func (o *PermissionController) GetByUser() { func (o *PermissionController) Get() { id := o.Ctx.Input.Param(":id") rel := o.Ctx.Input.Param(":relation") - role, err := infrastructure.GetPermissionConnector().GetPermission(id, rel) + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetPermission(id, rel) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -115,7 +119,8 @@ func (o *PermissionController) Get() { // @Success 200 {string} delete success! // @router /clear [delete] func (o *PermissionController) Clear() { - role, code, err := infrastructure.GetPermissionConnector().DeletePermission("", "", true) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).DeletePermission("", "", true) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -144,7 +149,8 @@ func (o *PermissionController) Bind() { permission_id := o.Ctx.Input.Param(":permission_id") role_id := o.Ctx.Input.Param(":role_id") rel := o.Ctx.Input.Param(":relation") - role, code, err := infrastructure.GetPermissionConnector().BindPermission(role_id, permission_id, rel) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).BindPermission(role_id, permission_id, rel) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -173,7 +179,8 @@ func (o *PermissionController) UnBind() { permission_id := o.Ctx.Input.Param(":permission_id") role_id := o.Ctx.Input.Param(":role_id") rel := o.Ctx.Input.Param(":relation") - role, code, err := infrastructure.GetPermissionConnector().UnBindPermission(role_id, permission_id, rel) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).UnBindPermission(role_id, permission_id, rel) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, diff --git a/controllers/role.go b/controllers/role.go index 206ff1d..bcabdc0 100644 --- a/controllers/role.go +++ b/controllers/role.go @@ -19,7 +19,8 @@ type RoleController struct { func (o *RoleController) Post() { // store and return Id or post with UUID id := o.Ctx.Input.Param(":id") - role, code, err := infrastructure.GetPermissionConnector().CreateRole(id) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).CreateRole(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -44,7 +45,8 @@ func (o *RoleController) Post() { // @router /user/:id [get] func (o *RoleController) GetByUser() { id := o.Ctx.Input.Param(":id") - role, err := infrastructure.GetPermissionConnector().GetRoleByUser(id) + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetRoleByUser(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -67,7 +69,8 @@ func (o *RoleController) GetByUser() { // @Success 200 {role} string // @router / [get] func (o *RoleController) GetAll() { - role, err := infrastructure.GetPermissionConnector().GetRole("") + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetRole("") if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -92,7 +95,8 @@ func (o *RoleController) GetAll() { // @router /:id [get] func (o *RoleController) Get() { id := o.Ctx.Input.Param(":id") - role, err := infrastructure.GetPermissionConnector().GetRole(id) + clientID := ExtractClient(*o.Ctx.Request) + role, err := infrastructure.GetPermissionConnector(clientID).GetRole(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -117,7 +121,8 @@ func (o *RoleController) Get() { // @router /:id [delete] func (o *RoleController) Delete() { id := o.Ctx.Input.Param(":id") - role, code, err := infrastructure.GetPermissionConnector().DeleteRole(id) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).DeleteRole(id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -140,7 +145,8 @@ func (o *RoleController) Delete() { // @Success 200 {string} delete success! // @router /clear [delete] func (o *RoleController) Clear() { - role, code, err := infrastructure.GetPermissionConnector().DeleteRole("") + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).DeleteRole("") if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -167,7 +173,8 @@ func (o *RoleController) Clear() { func (o *RoleController) Bind() { user_id := o.Ctx.Input.Param(":user_id") role_id := o.Ctx.Input.Param(":role_id") - role, code, err := infrastructure.GetPermissionConnector().BindRole(user_id, role_id) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).BindRole(user_id, role_id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, @@ -194,7 +201,8 @@ func (o *RoleController) Bind() { func (o *RoleController) UnBind() { user_id := o.Ctx.Input.Param(":user_id") role_id := o.Ctx.Input.Param(":role_id") - role, code, err := infrastructure.GetPermissionConnector().UnBindRole(user_id, role_id) + clientID := ExtractClient(*o.Ctx.Request) + role, code, err := infrastructure.GetPermissionConnector(clientID).UnBindRole(user_id, role_id) if err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, diff --git a/docker-compose-2.yml b/docker-compose-2.yml new file mode 100644 index 0000000..c72e378 --- /dev/null +++ b/docker-compose-2.yml @@ -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 \ No newline at end of file diff --git a/go.mod b/go.mod index a7ad333..f29b116 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module oc-auth go 1.22.0 require ( - cloud.o-forge.io/core/oc-lib v0.0.0-20241121074503-15ca06aba883 + cloud.o-forge.io/core/oc-lib v0.0.0-20250117152246-b85ca8674b27 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 @@ -15,6 +15,7 @@ require ( 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/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 @@ -36,6 +37,7 @@ require ( 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 @@ -44,6 +46,7 @@ require ( 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/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 diff --git a/go.sum b/go.sum index 0fe08bf..8b06b5b 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +cloud.o-forge.io/core/oc-lib v0.0.0-20240904135449-4f0ab6a3760f h1:v9mw3uNg/DJswOvHooMu8/BMedA+vIXbma+8iUwsjUI= +cloud.o-forge.io/core/oc-lib v0.0.0-20240904135449-4f0ab6a3760f/go.mod h1:FIJD0taWLJ5pjQLJ6sfE2KlTkvbmk5SMcyrxdjsaVz0= cloud.o-forge.io/core/oc-lib v0.0.0-20241016115009-b43226648692 h1:cfRhQioLwTBg9h1OOOp3VcUsBChO97M9lRDP8aq2Gkk= cloud.o-forge.io/core/oc-lib v0.0.0-20241016115009-b43226648692/go.mod h1:t+zpCTVKVdHH/BImwtMYY2QIWLMXKgY4n/JhFm3Vpu8= cloud.o-forge.io/core/oc-lib v0.0.0-20241016151521-9654d59fc076 h1:kPIBXPWdO47YdZClB/QYkt3EaReYS7Gs/c4FSXzhjtI= @@ -99,6 +101,76 @@ cloud.o-forge.io/core/oc-lib v0.0.0-20241121071546-e9b3a65a0ec6 h1:AdUkzaX63VF3f cloud.o-forge.io/core/oc-lib v0.0.0-20241121071546-e9b3a65a0ec6/go.mod h1:ya7Q+zHhaKM+XF6sAJ+avqHEVzaMnFJQih2X3TlTlGo= cloud.o-forge.io/core/oc-lib v0.0.0-20241121074503-15ca06aba883 h1:JdHJT8vuup4pJCC7rjiOe0/qD7at6400ml5zZHjEeUo= cloud.o-forge.io/core/oc-lib v0.0.0-20241121074503-15ca06aba883/go.mod h1:ya7Q+zHhaKM+XF6sAJ+avqHEVzaMnFJQih2X3TlTlGo= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202081145-cb21db672bb5 h1:qxXC6fkEa8bLTo0qn3VrB55tfxyjHQQa/0n97piJhNI= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202081145-cb21db672bb5/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202121923-2ec6899a1865 h1:BhGzhy6gsEA7vthuq6KWyABsRuF4KV5NqOvfkygytGg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202121923-2ec6899a1865/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202134851-9a2ed2351d7e h1:3U5JBdQRti2OpALLPhev6lkUi1TlYHgo2ADidOAfEAs= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202134851-9a2ed2351d7e/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202152644-e2ddd7e4e6f9 h1:qUA6T5Pjq/pv6dZYH4PWktXmFiRnloDX84m1U5NhvLM= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202152644-e2ddd7e4e6f9/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202155908-599a6144803e h1:3xGLiTDTgWHIIPDZyTo/clMIj+gQxnIDSE78s9/0wNE= +cloud.o-forge.io/core/oc-lib v0.0.0-20241202155908-599a6144803e/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203073336-6042d47700fd h1:iDryCORnODgAvBe1Yi+RnIGjYgUSkAv7ZCnm+CUV18w= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203073336-6042d47700fd/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203082527-2924ccd23b5c h1:3ghuxLEI3JXicDYoFx4YnkLauLl0Nq9UErjpL/2SqEU= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203082527-2924ccd23b5c/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203090110-471e0c9d9b48 h1:kVTpROPipS4YtROH9vAGZw21OMLNR48qbYedCngGThw= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203090110-471e0c9d9b48/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203095728-ea55c94c7328 h1:7iK2HzMm0EEEF60ajUVT/6jwqIirduww5Xa3191XS4I= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203095728-ea55c94c7328/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203105751-4b88da8ff66d h1:iIo+AMQ09MshkKKN8K8pd1ooLaigAYlnUUnQAaCidLo= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203105751-4b88da8ff66d/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203115141-6681c455d8e0 h1:RnHCONn0oYbEaTN1wDIeOAEM12cCZQRtvjBCVCb0b1Y= +cloud.o-forge.io/core/oc-lib v0.0.0-20241203115141-6681c455d8e0/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241204103308-fd01f535a131 h1:FdUY8b8xTdVzQ9wlphlo8TlbQif76V9oxGDYq26TsAs= +cloud.o-forge.io/core/oc-lib v0.0.0-20241204103308-fd01f535a131/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241204111455-1fcbc7c08ab0 h1:cBr4m2tcLf+dZufrjYvhvcsSqXcRDeyhnq5c5HY15po= +cloud.o-forge.io/core/oc-lib v0.0.0-20241204111455-1fcbc7c08ab0/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20241205082103-fbbce7817b73 h1:g96KMOxdhvM7x6YFqJfd08wybRzCLEvol7HfhKJfxO4= +cloud.o-forge.io/core/oc-lib v0.0.0-20241205082103-fbbce7817b73/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20250110164331-5255ffc2f728 h1:3p1G82xZmEAu2OEyY5HM42Cfbb1J887P9lSoRKNhgg8= +cloud.o-forge.io/core/oc-lib v0.0.0-20250110164331-5255ffc2f728/go.mod h1:2IevepXviessA6m67fB6ZJhZSeEeoOYWbVqPS4dzkbg= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113102407-21a7ff90104a h1:rrLSuAHI/TGOTm5d7Bffu+qf4EnmPguOll5x5nG/3Tc= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113102407-21a7ff90104a/go.mod h1:VgWEn23ddKySWXrwPMhqtiBjTJnbm5t7yWjzfvNxbbI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113114256-11905339bb24 h1:Kc51xKbnyfeafHpOJP7mWh9InNGqZUwcJR46008D+Eg= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113114256-11905339bb24/go.mod h1:VgWEn23ddKySWXrwPMhqtiBjTJnbm5t7yWjzfvNxbbI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113124812-6e5c87379649 h1:dmtrmNDdTR/2R3HjaIbPdu5LZViPzigwSjU207NXCxI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113124812-6e5c87379649/go.mod h1:VgWEn23ddKySWXrwPMhqtiBjTJnbm5t7yWjzfvNxbbI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113135241-a0f436b3e162 h1:oGP40P/uUngU7stnsRdx0jwxZGc+pzLzrMlUjEBSy0M= +cloud.o-forge.io/core/oc-lib v0.0.0-20250113135241-a0f436b3e162/go.mod h1:VgWEn23ddKySWXrwPMhqtiBjTJnbm5t7yWjzfvNxbbI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114071722-1c32cd2d12df h1:T52jgXQddoxwe+embR26Fwmz4G2jkl4QpYVHGtiLUNI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114071722-1c32cd2d12df/go.mod h1:VgWEn23ddKySWXrwPMhqtiBjTJnbm5t7yWjzfvNxbbI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114081637-918006302bb4 h1:AwCbDHjvUz9iQaF7hgYWyabVF/EzSSSk5bCNgntNJ6c= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114081637-918006302bb4/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114105339-b782248da741 h1:akAQLlcAXDtUhbNHbona9xJrHCzK9jxlvsDsEpVP1fg= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114105339-b782248da741/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114135055-1a4694c8913a h1:AxnecA1YKOZ81OKb1akK2Qc/0UNDUxdjSww7ALyehas= +cloud.o-forge.io/core/oc-lib v0.0.0-20250114135055-1a4694c8913a/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115082026-ad69c0495144 h1:MZ90rw4SKL0dqL/Lb+7E54vkk9fb8W6X0UJo9UW/XBk= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115082026-ad69c0495144/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115095644-be3803039583 h1:6My1sqjvqgHnC4TlE7RsZQHC8AVhad0gZl8uOvLTM9o= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115095644-be3803039583/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115102820-0e0540af43d0 h1:AcHC2WIeHOSjz5xe7OsjMi39EevxdY2O/9q0VMkDRz0= +cloud.o-forge.io/core/oc-lib v0.0.0-20250115102820-0e0540af43d0/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250116091455-68f418928395 h1:u4myLPGqBbzprWHg6713k5a++4yiq1ujlVy7yrMkZ9g= +cloud.o-forge.io/core/oc-lib v0.0.0-20250116091455-68f418928395/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250116142544-a4a249bab828 h1:yMDBDTs7LECyueUfh0iug502GN8GodVpQSl/gZchUjU= +cloud.o-forge.io/core/oc-lib v0.0.0-20250116142544-a4a249bab828/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117081640-450fab437cb7 h1:SV9U48sR09cNRl48489lQHrrKJFtTMQoQcRhmtsLTYQ= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117081640-450fab437cb7/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117090737-b990fe42d375 h1:UsPWfbVgvUcOC3BtD8B9dUQfv/FnRF4IZGrYxUJr1iM= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117090737-b990fe42d375/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117100508-d44fb976e4ff h1:GaLrVn6ame6BV7pfUB2xeHCCJLBECRiCCpPj6zteL+s= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117100508-d44fb976e4ff/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117121920-ed787683f47b h1:3wap+dPPplJkDglE5toKfdFUmjobAeIJWdiRtCQ3xkQ= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117121920-ed787683f47b/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117124801-e5c7dbe4cb96 h1:opQ/Uku27DOKAqDcKC9k6J9H5Tj9bNyKdHnJnD3U850= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117124801-e5c7dbe4cb96/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117135417-c63a1fef6c48 h1:dEebv8ZV5rt6BYPkcK6HOts+OPqkSxkKp5zn1lCq1vs= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117135417-c63a1fef6c48/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117152246-b85ca8674b27 h1:QEIj90eIoYsjs1uekbI3Nu48KDWmzGV7ugcr9agJbYI= +cloud.o-forge.io/core/oc-lib v0.0.0-20250117152246-b85ca8674b27/go.mod h1:2roQbUpv3a6mTIr5oU1ux31WbN8YucyyQvCQ0FqwbcE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8= github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= @@ -115,6 +187,8 @@ github.com/beego/beego/v2 v2.3.2/go.mod h1:5cqHsOHJIxkq44tBpRvtDe59GuVRVv/9/tyVD github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/biter777/countries v1.7.5 h1:MJ+n3+rSxWQdqVJU8eBy9RqcdH6ePPn4PJHocVWUa+Q= +github.com/biter777/countries v1.7.5/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -405,6 +479,8 @@ github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/marcinwyszynski/geopoint v0.0.0-20140302213024-cf2a6f750c5b h1:XBF8THPBy28s2ryI7+/Jf/847unLWxYMpJveX5Kox+0= +github.com/marcinwyszynski/geopoint v0.0.0-20140302213024-cf2a6f750c5b/go.mod h1:z1oqhOuuYpPHmUmAK2aNygKFlPdb4o3PppQnVTRFdrI= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -486,6 +562,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/purnaresa/bulwark v0.0.0-20201001150757-1cec324746b2 h1:5w7Y/+01L0ErOp3qFiiAEpVlvzYJK2mjbLFcbBkx2OI= github.com/purnaresa/bulwark v0.0.0-20201001150757-1cec324746b2/go.mod h1:/fUyI4rS5nHkKtgxNRU/uuFyhx9woSy3wKQSCQjqWN4= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= diff --git a/infrastructure/auth_connector/auth_connector.go b/infrastructure/auth_connector/auth_connector.go index 9032ddf..39a23ab 100644 --- a/infrastructure/auth_connector/auth_connector.go +++ b/infrastructure/auth_connector/auth_connector.go @@ -9,10 +9,10 @@ import ( type AuthConnector interface { Status() tools.State - Login(username string, cookies ...*http.Cookie) (*Token, error) - Logout(token string, cookies ...*http.Cookie) (*Token, error) + Login(clientID string, username string, cookies ...*http.Cookie) (*Token, error) + Logout(clientID string, token string, cookies ...*http.Cookie) (*Token, error) Introspect(token string, cookie ...*http.Cookie) (bool, error) - Refresh(token *Token) (*Token, error) + Refresh(client_id string, token *Token) (*Token, error) CheckAuthForward(reqToken string, publicKey string, host string, method string, forward string, external bool) bool } diff --git a/infrastructure/auth_connector/hydra_connector.go b/infrastructure/auth_connector/hydra_connector.go index eda0829..f89ee77 100644 --- a/infrastructure/auth_connector/hydra_connector.go +++ b/infrastructure/auth_connector/hydra_connector.go @@ -23,7 +23,6 @@ import ( type HydraConnector struct { State string `json:"state"` Scopes string `json:"scope"` - ClientID string `json:"client_id"` ResponseType string `json:"response_type"` Caller *tools.HTTPCaller @@ -85,7 +84,7 @@ func (a HydraConnector) challenge(username string, url string, challenge string, return &token, s[1], cookies, nil } -func (a HydraConnector) Refresh(token *Token) (*Token, error) { +func (a HydraConnector) Refresh(client_id string, token *Token) (*Token, error) { access := strings.Split(token.AccessToken, ".") if len(access) > 2 { token.AccessToken = strings.Join(access[0:2], ".") @@ -94,11 +93,11 @@ func (a HydraConnector) Refresh(token *Token) (*Token, error) { if err != nil || !isValid { return nil, err } - _, err = a.Logout(token.AccessToken) + _, err = a.Logout(client_id, token.AccessToken) if err != nil { return nil, err } - return a.Login(token.Username) + return a.Login(client_id, token.Username) } func (a HydraConnector) tryLog(username string, url string, subpath string, challenge string, cookies ...*http.Cookie) (*Redirect, string, []*http.Cookie, error) { @@ -120,7 +119,7 @@ func (a HydraConnector) tryLog(username string, url string, subpath string, chal return a.challenge(username, resp.Request.URL.String(), challenge, cookies...) } -func (a HydraConnector) getClient() string { +func (a HydraConnector) getClient(clientID string) string { resp, err := a.Caller.CallGet(a.getPath(true, false), "/clients") if err != nil { return "" @@ -130,11 +129,17 @@ func (a HydraConnector) getClient() string { if err != nil || len(clients) == 0 { return "" } + for _, c := range clients { + if c.(map[string]interface{})["client_name"].(string) == clientID { + return c.(map[string]interface{})["client_id"].(string) + } + } return clients[0].(map[string]interface{})["client_id"].(string) } -func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Token, err error) { - clientID := a.getClient() +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...) @@ -176,7 +181,7 @@ func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Toke return nil, err } json.Unmarshal(b, &m) - pp := oclib.Search(nil, strconv.Itoa(peer.SELF.EnumIndex()), oclib.LibDataEnum(oclib.PEER)) + pp := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).Search(nil, strconv.Itoa(peer.SELF.EnumIndex()), false) if len(pp.Data) == 0 || pp.Code >= 300 || pp.Err != "" { return nil, errors.New("peer not found") } @@ -184,7 +189,8 @@ func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Toke now = now.Add(time.Duration(token.ExpiresIn) * time.Second) unix := now.Unix() - c := claims.GetClaims().AddClaimsToToken(username, pp.Data[0].(*peer.Peer)) + 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) @@ -194,7 +200,8 @@ func (a HydraConnector) Login(username string, cookies ...*http.Cookie) (t *Toke return token, nil } -func (a HydraConnector) Logout(token string, cookies ...*http.Cookie) (*Token, error) { +func (a HydraConnector) Logout(clientID string, token string, cookies ...*http.Cookie) (*Token, error) { + clientID = a.getClient(clientID) access := strings.Split(token, ".") if len(access) > 2 { token = strings.Join(access[0:2], ".") @@ -202,7 +209,7 @@ func (a HydraConnector) Logout(token string, cookies ...*http.Cookie) (*Token, e p := a.getPath(false, true) + "/revoke" urls := url.Values{} urls.Add("token", token) - urls.Add("client_id", a.getClient()) + urls.Add("client_id", clientID) urls.Add("client_secret", conf.GetConfig().ClientSecret) _, err := a.Caller.CallForm(http.MethodPost, p, "", urls, "application/x-www-form-urlencoded", true) if err != nil { diff --git a/infrastructure/auth_connector/ldap.go b/infrastructure/auth_connector/ldap.go index aa3e823..0d0c57d 100644 --- a/infrastructure/auth_connector/ldap.go +++ b/infrastructure/auth_connector/ldap.go @@ -31,8 +31,9 @@ var ( type conn interface { Bind(bindDN, password string) error - SearchUser(user string, attrs ...string) ([]map[string]interface{}, error) - SearchUserRoles(user string, attrs ...string) ([]map[string]interface{}, error) + SearchRoles(attrs ...string) ([]map[string][]string, error) + SearchUser(user string, attrs ...string) ([]map[string][]string, error) + SearchUserRoles(user string, attrs ...string) ([]map[string][]string, error) Close() error } @@ -78,7 +79,7 @@ type Client struct { cache *freecache.Cache } -func (cli *Client) Authenticate(ctx context.Context, username, password string) (bool, error) { +func (cli *Client) Authenticate(ctx context.Context, username string, password string) (bool, error) { if username == "" || password == "" { return false, nil } @@ -101,8 +102,8 @@ func (cli *Client) Authenticate(ctx context.Context, username, password string) if details == nil { return false, nil } - - if err := cn.Bind(details["dn"].(string), password); err != nil { + a := details["dn"] + if err := cn.Bind(a[0], password); err != nil { if err == errInvalidCredentials { return false, nil } @@ -118,6 +119,21 @@ func (cli *Client) Authenticate(ctx context.Context, username, password string) return true, nil } +func (cli *Client) GetRoles(ctx context.Context) (map[string]LDAPRoles, error) { + var cancel context.CancelFunc + ctx, cancel = context.WithCancel(ctx) + + cn, ok := <-cli.connect(ctx) + cancel() + if !ok { + return map[string]LDAPRoles{}, errConnectionTimeout + } + defer cn.Close() + + // Find a user DN by his or her username. + return cli.findRoles(cn, "dn", "member", "uniqueMember") +} + // Claim is the FindOIDCClaims result struct type LDAPClaim struct { Code string // the root claim name @@ -125,6 +141,10 @@ type LDAPClaim struct { Value interface{} // the value } +type LDAPRoles struct { + Members map[string][]string +} + // FindOIDCClaims finds all OIDC claims for a user. func (cli *Client) FindOIDCClaims(ctx context.Context, username string) ([]LDAPClaim, error) { if username == "" { @@ -193,11 +213,12 @@ func (cli *Client) FindOIDCClaims(ctx context.Context, username string) ([]LDAPC roles := make(map[string]interface{}) for _, entry := range entries { - roleDN, ok := entry["dn"].(string) - if !ok || roleDN == "" { + roleDNs, ok := entry["dn"] + if !ok || len(roleDNs) == 0 { log.Infow("No required LDAP attribute for a role", "ldapAttribute", "dn", "entry", entry) continue } + roleDN := roleDNs[0] if entry[cli.RoleAttr] == nil { log.Infow("No required LDAP attribute for a role", "ldapAttribute", cli.RoleAttr, "roleDN", roleDN) continue @@ -278,8 +299,79 @@ func (cli *Client) connect(ctx context.Context) <-chan conn { return ch } +func (cli *Client) findRoles(cn conn, attrs ...string) (map[string]LDAPRoles, error) { + if cli.BindDN != "" { + // We need to login to a LDAP server with a service account for retrieving user data. + if err := cn.Bind(cli.BindDN, cli.BindPass); err != nil { + return map[string]LDAPRoles{}, errors.New(err.Error() + " : failed to login to a LDAP woth a service account") + } + } + entries, err := cn.SearchRoles(attrs...) + fmt.Println("entries", entries) + if err != nil { + return map[string]LDAPRoles{}, err + } + claims := map[string]LDAPRoles{} + for _, entry := range entries { + roleDNs, ok := entry["dn"] + if !ok || len(roleDNs) == 0 { + continue + } + roleDN := roleDNs[0] + // Ensure that a role's DN is inside of the role's base DN. + // 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) { + 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. + path := strings.Split(roleDN[:n-k-1], ",") + if len(path) != 2 { + continue + } + appID := path[1][len("OU="):] + if _, ok := claims[appID]; !ok { + claims[appID] = LDAPRoles{ + Members: map[string][]string{}, + } + } + role := path[0][len("cn="):] + if claims[appID].Members[role] == nil { + claims[appID].Members[role] = []string{} + } + fmt.Println("entry", entry) + memberDNs, ok := entry["member"] + for _, memberDN := range memberDNs { + if !ok || memberDN == "" { + continue + } + path = strings.Split(memberDN[:n-k-1], ",") + if len(path) < 1 { + continue + } + member := strings.Split(path[0][len("uid="):], ",") + claims[appID].Members[role] = append(claims[appID].Members[role], member[0]) + } + memberDNs, ok = entry["uniqueMember"] + for _, memberDN := range memberDNs { + if !ok || memberDN == "" { + continue + } + path = strings.Split(memberDN[:n-k-1], ",") + if len(path) < 1 { + continue + } + member := strings.Split(path[0][len("uid="):], ",") + claims[appID].Members[role] = append(claims[appID].Members[role], member[0]) + } + } + + return claims, nil +} + // findBasicUserDetails finds user's LDAP attributes that were specified. It returns nil if no such user. -func (cli *Client) findBasicUserDetails(cn conn, username string, attrs []string) (map[string]interface{}, error) { +func (cli *Client) findBasicUserDetails(cn conn, username string, attrs []string) (map[string][]string, error) { if cli.BindDN != "" { // We need to login to a LDAP server with a service account for retrieving user data. if err := cn.Bind(cli.BindDN, cli.BindPass); err != nil { @@ -298,7 +390,7 @@ func (cli *Client) findBasicUserDetails(cn conn, username string, attrs []string var ( entry = entries[0] - details = make(map[string]interface{}) + details = make(map[string][]string) ) for _, attr := range attrs { if v, ok := entry[attr]; ok { @@ -349,35 +441,40 @@ func (c *ldapConn) Bind(bindDN, password string) error { return err } -func (c *ldapConn) SearchUser(user string, attrs ...string) ([]map[string]interface{}, error) { +func (c *ldapConn) SearchUser(user string, attrs ...string) ([]map[string][]string, error) { query := fmt.Sprintf( "(&(|(objectClass=organizationalPerson)(objectClass=inetOrgPerson))"+ "(|(uid=%[1]s)(mail=%[1]s)(userPrincipalName=%[1]s)(sAMAccountName=%[1]s)))", user) return c.searchEntries(c.BaseDN, query, attrs) } -func (c *ldapConn) SearchUserRoles(user string, attrs ...string) ([]map[string]interface{}, error) { +func (c *ldapConn) SearchUserRoles(user string, attrs ...string) ([]map[string][]string, error) { query := fmt.Sprintf("(|"+ - "(&(|(objectClass=group)(objectClass=groupOfNames))(member=%[1]s))"+ + "(&(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupofnames))(member=%[1]s))"+ "(&(objectClass=groupOfUniqueNames)(uniqueMember=%[1]s))"+ ")", user) return c.searchEntries(c.RoleBaseDN, query, attrs) } +func (c *ldapConn) SearchRoles(attrs ...string) ([]map[string][]string, error) { + query := "(|(&(|(objectClass=group)(objectClass=groupOfNames)(objectClass=groupofnames))))" + return c.searchEntries(c.RoleBaseDN, query, attrs) +} + // searchEntries executes a LDAP query, and returns a result as entries where each entry is mapping of LDAP attributes. -func (c *ldapConn) searchEntries(baseDN, query string, attrs []string) ([]map[string]interface{}, error) { +func (c *ldapConn) searchEntries(baseDN, query string, attrs []string) ([]map[string][]string, error) { req := ldap.NewSearchRequest(baseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false, query, attrs, nil) res, err := c.Search(req) if err != nil { return nil, err } - var entries []map[string]interface{} + var entries []map[string][]string for _, v := range res.Entries { - entry := map[string]interface{}{"dn": v.DN} + entry := map[string][]string{"dn": []string{v.DN}} for _, attr := range v.Attributes { // We need the first value only for the named attribute. - entry[attr.Name] = attr.Values[0] + entry[attr.Name] = attr.Values } entries = append(entries, entry) } diff --git a/infrastructure/claims/claims.go b/infrastructure/claims/claims.go index f326b07..7281a65 100644 --- a/infrastructure/claims/claims.go +++ b/infrastructure/claims/claims.go @@ -8,7 +8,7 @@ import ( // Tokenizer interface type ClaimService interface { - AddClaimsToToken(userId string, peer *peer.Peer) Claims + AddClaimsToToken(clientID string, userId string, peer *peer.Peer) Claims DecodeClaimsInToken(host string, method string, forward string, sessionClaims Claims, publicKey string, external bool) (bool, error) } diff --git a/infrastructure/claims/hydra_claims.go b/infrastructure/claims/hydra_claims.go index 6389253..c89b254 100644 --- a/infrastructure/claims/hydra_claims.go +++ b/infrastructure/claims/hydra_claims.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/pem" "errors" + "fmt" "oc-auth/conf" "oc-auth/infrastructure/perms_connectors" "oc-auth/infrastructure/utils" @@ -119,21 +120,23 @@ func (h HydraClaims) DecodeClaimsInToken(host string, method string, forward str Relation: "permits" + strings.ToUpper(meth.String()), Object: p.(string), } - return perms_connectors.GetPermissionConnector().CheckPermission(perm, nil, true), nil + return perms_connectors.GetPermissionConnector("").CheckPermission(perm, nil, true), nil } } return false, errors.New("no permission found") } // add claims to token method of HydraTokenizer -func (h HydraClaims) AddClaimsToToken(userId string, p *peer.Peer) Claims { +func (h HydraClaims) AddClaimsToToken(clientID string, userId string, p *peer.Peer) Claims { claims := Claims{} perms, err := perms_connectors.KetoConnector{}.GetPermissionByUser(userId, true) + if err != nil { return claims } claims.Session.AccessToken = make(map[string]interface{}) claims.Session.IDToken = make(map[string]interface{}) + fmt.Println("PERMS err 1", perms, err) for _, perm := range perms { key, err := h.generateKey(strings.ReplaceAll(perm.Relation, "permits", ""), perm.Subject) if err != nil { @@ -145,15 +148,15 @@ func (h HydraClaims) AddClaimsToToken(userId string, p *peer.Peer) Claims { if err != nil { return claims } + claims.Session.IDToken["username"] = userId claims.Session.IDToken["peer_id"] = p.UUID // we should get group from user groups, err := perms_connectors.KetoConnector{}.GetGroupByUser(userId) if err != nil { return claims } + claims.Session.IDToken["client_id"] = clientID claims.Session.IDToken["groups"] = groups claims.Session.IDToken["signature"] = sign return claims } - -// add signature in the token MISSING diff --git a/infrastructure/infrastructure.go b/infrastructure/infrastructure.go index 1d78dcc..b08768c 100644 --- a/infrastructure/infrastructure.go +++ b/infrastructure/infrastructure.go @@ -10,8 +10,8 @@ func GetAuthConnector() auth_connectors.AuthConnector { return auth_connectors.GetAuthConnector() } -func GetPermissionConnector() perms_connectors.PermConnector { - return perms_connectors.GetPermissionConnector() +func GetPermissionConnector(client string) perms_connectors.PermConnector { + return perms_connectors.GetPermissionConnector(client) } func GetClaims() claims.ClaimService { diff --git a/infrastructure/perms_connectors/keto_connector.go b/infrastructure/perms_connectors/keto_connector.go index 9cb4051..0fc7938 100644 --- a/infrastructure/perms_connectors/keto_connector.go +++ b/infrastructure/perms_connectors/keto_connector.go @@ -6,24 +6,29 @@ import ( "fmt" "oc-auth/conf" "oc-auth/infrastructure/utils" - "strings" oclib "cloud.o-forge.io/core/oc-lib" "cloud.o-forge.io/core/oc-lib/tools" ) -type KetoConnector struct{} +type KetoConnector struct { + Client string +} + +func (k KetoConnector) SetClient(client string) { + k.Client = client +} func (k KetoConnector) namespace() string { return "open-cloud" } func (k KetoConnector) scope() string { - return "oc-auth" + return "oc-auth-realm" } func (f KetoConnector) permToQuery(perm Permission, permDependancies *Permission) string { - n := "?namespace=" + perm.Namespace() + n := "?namespace=" + f.namespace() if perm.Object != "" { n += "&object=" + perm.Object } @@ -189,6 +194,7 @@ func (k KetoConnector) GetPermissionByRole(roleID string) ([]Permission, error) } func (k KetoConnector) GetPermissionByUser(userID string, internal bool) ([]Permission, error) { roles, err := k.get("", "member", userID) + fmt.Println("ROLES", roles, err) if err != nil { return nil, err } @@ -235,7 +241,7 @@ func (k KetoConnector) get(object string, relation string, subject string) ([]Pe return t, nil } -func (k KetoConnector) binds(subject string, relation string, object string) (string, int, error) { +func (k KetoConnector) binds(object string, relation string, subject string) (string, int, error) { _, code, err := k.createRelationShip(object, relation, subject, nil) if err != nil { return object, code, err @@ -244,6 +250,7 @@ func (k KetoConnector) binds(subject string, relation string, object string) (st } func (k KetoConnector) BindRole(userID string, roleID string) (string, int, error) { + fmt.Println("BIND ROLE", userID, roleID) return k.binds(userID, "member", roleID) } @@ -324,9 +331,6 @@ func (k KetoConnector) UnBindPermission(roleID string, permID string, relation s } func (k KetoConnector) createRelationShip(object string, relation string, subject string, subPerm *Permission) (*Permission, int, error) { exist, err := k.get(object, relation, subject) - if strings.Contains(subject, "/workflow/:id") { - fmt.Println("subject", subject, relation, exist, err) - } if err == nil && len(exist) > 0 { return nil, 409, errors.New("Relation already exist") } @@ -338,7 +342,7 @@ func (k KetoConnector) createRelationShip(object string, relation string, subjec if err != nil { return nil, code, err } - body["subject_set"] = map[string]interface{}{"namespace": s.Namespace(), "object": s.Object, "relation": s.Relation, "subject_id": s.Subject} + body["subject_set"] = map[string]interface{}{"namespace": k.namespace(), "object": s.Object, "relation": s.Relation, "subject_id": s.Subject} } host := conf.GetConfig().PermissionConnectorHost port := fmt.Sprintf("%v", conf.GetConfig().PermissionConnectorAdminPort) diff --git a/infrastructure/perms_connectors/perms_connector.go b/infrastructure/perms_connectors/perms_connector.go index a51556f..9560725 100644 --- a/infrastructure/perms_connectors/perms_connector.go +++ b/infrastructure/perms_connectors/perms_connector.go @@ -23,6 +23,7 @@ func (k Permission) Scope() string { type PermConnector interface { Status() tools.State + SetClient(scope string) CheckPermission(perm Permission, permDependancies *Permission, internal bool) bool BindRole(userID string, roleID string) (string, int, error) BindGroup(userID string, groupID string) (string, int, error) @@ -53,6 +54,6 @@ var c = map[string]PermConnector{ "keto": KetoConnector{}, } -func GetPermissionConnector() PermConnector { +func GetPermissionConnector(scope string) PermConnector { return c[conf.GetConfig().PermissionConnectorHost] } diff --git a/ldap-hydra/docker-compose-2.yml b/ldap-hydra/docker-compose-2.yml new file mode 100644 index 0000000..2fe27d0 --- /dev/null +++ b/ldap-hydra/docker-compose-2.yml @@ -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 diff --git a/ldap-hydra/ldap-2.ldif b/ldap-hydra/ldap-2.ldif new file mode 100644 index 0000000..79ac6b6 --- /dev/null +++ b/ldap-hydra/ldap-2.ldif @@ -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 \ No newline at end of file diff --git a/main.go b/main.go index cd860bf..ac98897 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,12 @@ package main import ( + "context" "errors" + "fmt" "oc-auth/conf" "oc-auth/infrastructure" + auth_connectors "oc-auth/infrastructure/auth_connector" _ "oc-auth/routers" "os" "strconv" @@ -42,6 +45,7 @@ func main() { conf.GetConfig().PermissionConnectorAdminPort = o.GetIntDefault("PERMISSION_CONNECTOR_ADMIN_PORT", 4467) // config LDAP + conf.GetConfig().SourceMode = o.GetStringDefault("SOURCE_MODE", "ldap") conf.GetConfig().LDAPEndpoints = o.GetStringDefault("LDAP_ENDPOINTS", "ldap:389") conf.GetConfig().LDAPBindDN = o.GetStringDefault("LDAP_BINDDN", "cn=admin,dc=example,dc=com") conf.GetConfig().LDAPBindPW = o.GetStringDefault("LDAP_BINDPW", "password") @@ -51,10 +55,36 @@ func main() { if err != nil { panic(err) } + generateRole() discovery() beego.Run() } +func generateRole() { + defer func() { + if r := recover(); r != nil { + fmt.Println("Recovered in f", r) + } + }() + // if from ldap, create roles from ldap + if conf.GetConfig().SourceMode == "ldap" { + ldap := auth_connectors.New() + roles, err := ldap.GetRoles(context.Background()) + 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) + } + } + } + } +} + func generateSelfPeer() error { // TODO check if files at private & public path are set // check if files at private & public path are set @@ -65,7 +95,7 @@ func generateSelfPeer() error { return errors.New("public key path does not exist") } // check if peer already exists - p := oclib.Search(nil, strconv.Itoa(peer.SELF.EnumIndex()), oclib.LibDataEnum(oclib.PEER)) + p := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).Search(nil, strconv.Itoa(peer.SELF.EnumIndex()), false) file := "" f, err := os.ReadFile(conf.GetConfig().PublicKeyPath) if err != nil { @@ -90,7 +120,7 @@ func generateSelfPeer() error { PublicKey: file, State: peer.SELF, } - data := oclib.StoreOne(oclib.LibDataEnum(oclib.PEER), peer.Serialize()) + data := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), "", "", []string{}, nil).StoreOne(peer.Serialize(peer)) if data.Err != "" { return errors.New(data.Err) } @@ -99,7 +129,7 @@ func generateSelfPeer() error { func discovery() { api := tools.API{} - conn := infrastructure.GetPermissionConnector() + conn := infrastructure.GetPermissionConnector("") conn.CreateRole(conf.GetConfig().AdminRole) conn.BindRole(conf.GetConfig().AdminRole, "admin") diff --git a/oc-auth b/oc-auth index 2706af9..3e2ea4b 100755 Binary files a/oc-auth and b/oc-auth differ diff --git a/routers/commentsRouter.go b/routers/commentsRouter.go index e18f62f..2c3767f 100644 --- a/routers/commentsRouter.go +++ b/routers/commentsRouter.go @@ -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(), @@ -99,8 +99,8 @@ func init() { beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"] = append(beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"], beego.ControllerComments{ - Method: "LoginLDAP", - Router: `/ldap/login`, + Method: "Login", + Router: `/login`, AllowHTTPMethods: []string{"post"}, MethodParams: param.Make(), Filters: nil, @@ -108,8 +108,8 @@ func init() { beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"] = append(beego.GlobalControllerRouter["oc-auth/controllers:OAuthController"], beego.ControllerComments{ - Method: "LogOutLDAP", - Router: `/ldap/logout`, + Method: "LogOut", + Router: `/logout`, AllowHTTPMethods: []string{"delete"}, MethodParams: param.Make(), Filters: nil, diff --git a/swagger/swagger.json b/swagger/swagger.json index 77a837c..9b17f52 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -191,7 +191,7 @@ "parameters": [ { "in": "path", - "name": "group_id", + "name": "user_id", "description": "The group_id you want to unbind", "required": true, "type": "string" @@ -233,7 +233,7 @@ } } }, - "/ldap/login": { + "/login": { "post": { "tags": [ "oc-auth/controllersOAuthController" @@ -249,6 +249,13 @@ "schema": { "$ref": "#/definitions/models.workflow" } + }, + { + "in": "query", + "name": "client_id", + "description": "the client_id you want to get", + "required": true, + "type": "string" } ], "responses": { @@ -258,7 +265,7 @@ } } }, - "/ldap/logout": { + "/logout": { "delete": { "tags": [ "oc-auth/controllersOAuthController" @@ -271,6 +278,13 @@ "name": "Authorization", "description": "auth token", "type": "string" + }, + { + "in": "query", + "name": "client_id", + "description": "the client_id you want to get", + "required": true, + "type": "string" } ], "responses": { @@ -465,6 +479,13 @@ "schema": { "$ref": "#/definitions/models.Token" } + }, + { + "in": "query", + "name": "client_id", + "description": "the client_id you want to get", + "required": true, + "type": "string" } ], "responses": { diff --git a/swagger/swagger.yml b/swagger/swagger.yml index fd70eef..bc87b31 100644 --- a/swagger/swagger.yml +++ b/swagger/swagger.yml @@ -119,7 +119,7 @@ paths: operationId: GroupController.UnBind parameters: - in: path - name: group_id + name: user_id description: The group_id you want to unbind required: true type: string @@ -175,7 +175,7 @@ paths: responses: "200": description: '{string}' - /ldap/login: + /login: post: tags: - oc-auth/controllersOAuthController @@ -190,10 +190,15 @@ paths: required: true schema: $ref: '#/definitions/models.workflow' + - in: query + name: client_id + description: the client_id you want to get + required: true + type: string responses: "200": description: '{string}' - /ldap/logout: + /logout: delete: tags: - oc-auth/controllersOAuthController @@ -206,6 +211,11 @@ paths: name: Authorization description: auth token type: string + - in: query + name: client_id + description: the client_id you want to get + required: true + type: string responses: "200": description: '{string}' @@ -350,6 +360,11 @@ paths: required: true schema: $ref: '#/definitions/models.Token' + - in: query + name: client_id + description: the client_id you want to get + required: true + type: string responses: "200": description: '{string}'