Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
{
"GOLANG": {
"TOO_MANY_IVARS": [1000, 2000, 3000, 4000],
"ARITY": [1000, 2000, 3000, 4000]
}
}
+19
View File
@@ -0,0 +1,19 @@
*.orig
# Other stuff aslong as i'm to lazy to use environment variables
*.secret.go
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
\.idea/
+44
View File
@@ -0,0 +1,44 @@
run:
skip-dirs:
- (^|/)testdata($|/)
skip-dirs-use-default: false
linters:
enable:
- goimports
- gofmt
- misspell
- gosec
- unconvert
- revive
- gocognit
- gocyclo
fast: true
linters-settings:
misspell:
locale: US
golint:
min-confidence: 0
govet:
check-shadowing: false
goimports:
local-prefixes: github.com/Nerzal/gocloak
gocognit:
min-complexity: 15
gocyclo:
min-complexity: 15
gofmt:
simplify: true
issues:
exclude-use-default: false
exclude-rules:
- path: _test\.go
linters:
- gocyclo
- dupl
- gosec
- gocognit
exclude:
- should have a package comment
+1
View File
@@ -0,0 +1 @@
CVE-2022-32149
+11
View File
@@ -0,0 +1,11 @@
FROM quay.io/keycloak/keycloak:19.0
COPY testdata data/import
WORKDIR /opt/keycloak
ENV KC_HOSTNAME=localhost
ENV KEYCLOAK_USER=admin
ENV KEYCLOAK_PASSWORD=secret
ENV KEYCLOAK_ADMIN=admin
ENV KEYCLOAK_ADMIN_PASSWORD=secret
ENV KC_FEATURES=account-api,account2,authorization,client-policies,impersonation,docker,scripts,upload_scripts,admin-fine-grained-authz
RUN /opt/keycloak/bin/kc.sh import --file /data/import/gocloak-realm.json
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [2021] [Tobias Theel]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+8
View File
@@ -0,0 +1,8 @@
test:
./run-tests.sh
start-keycloak: stop-keycloak
docker-compose up -d
stop-keycloak:
docker-compose down
+2
View File
@@ -0,0 +1,2 @@
Thanks for your contribution!
Hi, if there is an issue, that your PR adresses, please link it!
+496
View File
@@ -0,0 +1,496 @@
# gocloak
[![codebeat badge](https://codebeat.co/badges/18a37f35-6a95-4e40-9e78-272233892332)](https://codebeat.co/projects/github-com-nerzal-gocloak-main)
[![Go Report Card](https://goreportcard.com/badge/github.com/Nerzal/gocloak)](https://goreportcard.com/report/github.com/Nerzal/gocloak)
[![Go Doc](https://godoc.org/github.com/Nerzal/gocloak?status.svg)](https://godoc.org/github.com/Nerzal/gocloak)
[![Build Status](https://github.com/Nerzal/gocloak/workflows/Tests/badge.svg)](https://github.com/Nerzal/gocloak/actions?query=branch%3Amain+event%3Apush)
[![GitHub release](https://img.shields.io/github/tag/Nerzal/gocloak.svg)](https://GitHub.com/Nerzal/gocloak/releases/)
[![codecov](https://codecov.io/gh/Nerzal/gocloak/branch/master/graph/badge.svg)](https://codecov.io/gh/Nerzal/gocloak)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FNerzal%2Fgocloak.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FNerzal%2Fgocloak?ref=badge_shield)
Golang Keycloak API Package
This client is based on: [go-keycloak](https://github.com/PhilippHeuer/go-keycloak)
For Questions either raise an issue, or come to the [gopher-slack](https://invite.slack.golangbridge.org/) into the channel [#gocloak](https://gophers.slack.com/app_redirect?channel=gocloak)
If u are using the echo framework have a look at [gocloak-echo](https://github.com/Nerzal/gocloak-echo)
Benchmarks can be found [here](https://nerzal.github.io/gocloak/dev/bench/)
## Contribution
(WIP) <https://github.com/Nerzal/gocloak/wiki/Contribute>
## Changelog
For release notes please consult the specific releases [here](https://github.com/Nerzal/gocloak/releases)
## Usage
### Installation
```shell
go get github.com/Nerzal/gocloak/v13
```
### Importing
```go
import "github.com/Nerzal/gocloak/v13"
```
### Create New User
```go
client := gocloak.NewClient("https://mycool.keycloak.instance")
ctx := context.Background()
token, err := client.LoginAdmin(ctx, "user", "password", "realmName")
if err != nil {
panic("Something wrong with the credentials or url")
}
user := gocloak.User{
FirstName: gocloak.StringP("Bob"),
LastName: gocloak.StringP("Uncle"),
Email: gocloak.StringP("something@really.wrong"),
Enabled: gocloak.BoolP(true),
Username: gocloak.StringP("CoolGuy"),
}
_, err = client.CreateUser(ctx, token.AccessToken, "realm", user)
if err != nil {
panic("Oh no!, failed to create user :(")
}
```
### Introspect Token
```go
client := gocloak.NewClient(hostname)
ctx := context.Background()
token, err := client.LoginClient(ctx, clientID, clientSecret, realm)
if err != nil {
panic("Login failed:"+ err.Error())
}
rptResult, err := client.RetrospectToken(ctx, token.AccessToken, clientID, clientSecret, realm)
if err != nil {
panic("Inspection failed:"+ err.Error())
}
if !*rptResult.Active {
panic("Token is not active")
}
permissions := rptResult.Permissions
// Do something with the permissions ;)
```
### Get Client id
Client has 2 identity fields- `id` and `clientId` and both are unique in one realm.
- `id` is generated automatically by Keycloak.
- `clientId` is configured by users in `Add client` page.
To get the `clientId` from `id`, use `GetClients` method with `GetClientsParams{ClientID: &clientName}`.
```go
clients, err := c.Client.GetClients(
c.Ctx,
c.JWT.AccessToken,
c.Realm,
gocloak.GetClientsParams{
ClientID: &clientName,
},
)
if err != nil {
panic("List clients failed:"+ err.Error())
}
for _, client := range clients {
return *client.ID, nil
}
```
## Features
```go
// GoCloak holds all methods a client should fulfill
type GoCloak interface {
RestyClient() *resty.Client
SetRestyClient(restyClient *resty.Client)
GetToken(ctx context.Context, realm string, options TokenOptions) (*JWT, error)
GetRequestingPartyToken(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*JWT, error)
GetRequestingPartyPermissions(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*[]RequestingPartyPermission, error)
GetRequestingPartyPermissionDecision(ctx context.Context, token, realm string, options RequestingPartyTokenOptions) (*RequestingPartyPermissionDecision, error)
Login(ctx context.Context, clientID, clientSecret, realm, username, password string) (*JWT, error)
LoginOtp(ctx context.Context, clientID, clientSecret, realm, username, password, totp string) (*JWT, error)
Logout(ctx context.Context, clientID, clientSecret, realm, refreshToken string) error
LogoutPublicClient(ctx context.Context, clientID, realm, accessToken, refreshToken string) error
LogoutAllSessions(ctx context.Context, accessToken, realm, userID string) error
RevokeUserConsents(ctx context.Context, accessToken, realm, userID, clientID string) error
LogoutUserSession(ctx context.Context, accessToken, realm, session string) error
LoginClient(ctx context.Context, clientID, clientSecret, realm string) (*JWT, error)
LoginClientSignedJWT(ctx context.Context, clientID, realm string, key interface{}, signedMethod jwt.SigningMethod, expiresAt *jwt.Time) (*JWT, error)
LoginAdmin(ctx context.Context, username, password, realm string) (*JWT, error)
RefreshToken(ctx context.Context, refreshToken, clientID, clientSecret, realm string) (*JWT, error)
DecodeAccessToken(ctx context.Context, accessToken, realm, expectedAudience string) (*jwt.Token, *jwt.MapClaims, error)
DecodeAccessTokenCustomClaims(ctx context.Context, accessToken, realm, expectedAudience string, claims jwt.Claims) (*jwt.Token, error)
RetrospectToken(ctx context.Context, accessToken, clientID, clientSecret, realm string) (*RetrospecTokenResult, error)
GetIssuer(ctx context.Context, realm string) (*IssuerResponse, error)
GetCerts(ctx context.Context, realm string) (*CertResponse, error)
GetServerInfo(ctx context.Context, accessToken string) (*ServerInfoRepesentation, error)
GetUserInfo(ctx context.Context, accessToken, realm string) (*UserInfo, error)
GetRawUserInfo(ctx context.Context, accessToken, realm string) (map[string]interface{}, error)
SetPassword(ctx context.Context, token, userID, realm, password string, temporary bool) error
ExecuteActionsEmail(ctx context.Context, token, realm string, params ExecuteActionsEmail) error
CreateUser(ctx context.Context, token, realm string, user User) (string, error)
CreateGroup(ctx context.Context, accessToken, realm string, group Group) (string, error)
CreateChildGroup(ctx context.Context, token, realm, groupID string, group Group) (string, error)
CreateClientRole(ctx context.Context, accessToken, realm, idOfClient string, role Role) (string, error)
CreateClient(ctx context.Context, accessToken, realm string, newClient Client) (string, error)
CreateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) (string, error)
CreateComponent(ctx context.Context, accessToken, realm string, component Component) (string, error)
CreateClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string, roles []Role) error
CreateClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string, roles []Role) error
CreateClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfCLientScope string, roles []Role) error
CreateClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, idOfClient string, roles []Role) error
UpdateUser(ctx context.Context, accessToken, realm string, user User) error
UpdateGroup(ctx context.Context, accessToken, realm string, updatedGroup Group) error
UpdateRole(ctx context.Context, accessToken, realm, idOfClient string, role Role) error
UpdateClient(ctx context.Context, accessToken, realm string, updatedClient Client) error
UpdateClientScope(ctx context.Context, accessToken, realm string, scope ClientScope) error
DeleteUser(ctx context.Context, accessToken, realm, userID string) error
DeleteComponent(ctx context.Context, accessToken, realm, componentID string) error
DeleteGroup(ctx context.Context, accessToken, realm, groupID string) error
DeleteClientRole(ctx context.Context, accessToken, realm, idOfClient, roleName string) error
DeleteClientRoleFromUser(ctx context.Context, token, realm, idOfClient, userID string, roles []Role) error
DeleteClient(ctx context.Context, accessToken, realm, idOfClient string) error
DeleteClientScope(ctx context.Context, accessToken, realm, scopeID string) error
DeleteClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string, roles []Role) error
DeleteClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string, roles []Role) error
DeleteClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfCLientScope string, roles []Role) error
DeleteClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, ifOfClient string, roles []Role) error
GetClient(ctx context.Context, accessToken, realm, idOfClient string) (*Client, error)
GetClientsDefaultScopes(ctx context.Context, token, realm, idOfClient string) ([]*ClientScope, error)
AddDefaultScopeToClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
RemoveDefaultScopeFromClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
GetClientsOptionalScopes(ctx context.Context, token, realm, idOfClient string) ([]*ClientScope, error)
AddOptionalScopeToClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
RemoveOptionalScopeFromClient(ctx context.Context, token, realm, idOfClient, scopeID string) error
GetDefaultOptionalClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
GetDefaultDefaultClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
GetClientScope(ctx context.Context, token, realm, scopeID string) (*ClientScope, error)
GetClientScopes(ctx context.Context, token, realm string) ([]*ClientScope, error)
GetClientScopeMappings(ctx context.Context, token, realm, idOfClient string) (*MappingsRepresentation, error)
GetClientScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClient string) ([]*Role, error)
GetClientScopeMappingsRealmRolesAvailable(ctx context.Context, token, realm, idOfClient string) ([]*Role, error)
GetClientScopesScopeMappingsRealmRolesAvailable(ctx context.Context, token, realm, idOfClientScope string) ([]*Role, error)
GetClientScopesScopeMappingsClientRolesAvailable(ctx context.Context, token, realm, idOfClientScope, idOfClient string) ([]*Role, error)
GetClientScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string) ([]*Role, error)
GetClientScopesScopeMappingsRealmRoles(ctx context.Context, token, realm, idOfClientScope string) ([]*Role, error)
GetClientScopesScopeMappingsClientRoles(ctx context.Context, token, realm, idOfClientScope, idOfClient string) ([]*Role, error)
GetClientScopeMappingsClientRolesAvailable(ctx context.Context, token, realm, idOfClient, idOfSelectedClient string) ([]*Role, error)
GetClientSecret(ctx context.Context, token, realm, idOfClient string) (*CredentialRepresentation, error)
GetClientServiceAccount(ctx context.Context, token, realm, idOfClient string) (*User, error)
RegenerateClientSecret(ctx context.Context, token, realm, idOfClient string) (*CredentialRepresentation, error)
GetKeyStoreConfig(ctx context.Context, accessToken, realm string) (*KeyStoreConfig, error)
GetUserByID(ctx context.Context, accessToken, realm, userID string) (*User, error)
GetUserCount(ctx context.Context, accessToken, realm string, params GetUsersParams) (int, error)
GetUsers(ctx context.Context, accessToken, realm string, params GetUsersParams) ([]*User, error)
GetUserGroups(ctx context.Context, accessToken, realm, userID string, params GetGroupsParams) ([]*UserGroup, error)
AddUserToGroup(ctx context.Context, token, realm, userID, groupID string) error
DeleteUserFromGroup(ctx context.Context, token, realm, userID, groupID string) error
GetComponents(ctx context.Context, accessToken, realm string) ([]*Component, error)
GetGroups(ctx context.Context, accessToken, realm string, params GetGroupsParams) ([]*Group, error)
GetGroupsCount(ctx context.Context, token, realm string, params GetGroupsParams) (int, error)
GetGroup(ctx context.Context, accessToken, realm, groupID string) (*Group, error)
GetDefaultGroups(ctx context.Context, accessToken, realm string) ([]*Group, error)
AddDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error
RemoveDefaultGroup(ctx context.Context, accessToken, realm, groupID string) error
GetGroupMembers(ctx context.Context, accessToken, realm, groupID string, params GetGroupsParams) ([]*User, error)
GetRoleMappingByGroupID(ctx context.Context, accessToken, realm, groupID string) (*MappingsRepresentation, error)
GetRoleMappingByUserID(ctx context.Context, accessToken, realm, userID string) (*MappingsRepresentation, error)
GetClientRoles(ctx context.Context, accessToken, realm, idOfClient string, params GetRoleParams) ([]*Role, error)
GetClientRole(ctx context.Context, token, realm, idOfClient, roleName string) (*Role, error)
GetClientRoleByID(ctx context.Context, accessToken, realm, roleID string) (*Role, error)
GetClients(ctx context.Context, accessToken, realm string, params GetClientsParams) ([]*Client, error)
AddClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error
DeleteClientRoleComposite(ctx context.Context, token, realm, roleID string, roles []Role) error
GetUsersByRoleName(ctx context.Context, token, realm, roleName string) ([]*User, error)
GetUsersByClientRoleName(ctx context.Context, token, realm, idOfClient, roleName string, params GetUsersByRoleParams) ([]*User, error)
CreateClientProtocolMapper(ctx context.Context, token, realm, idOfClient string, mapper ProtocolMapperRepresentation) (string, error)
UpdateClientProtocolMapper(ctx context.Context, token, realm, idOfClient, mapperID string, mapper ProtocolMapperRepresentation) error
DeleteClientProtocolMapper(ctx context.Context, token, realm, idOfClient, mapperID string) error
// *** Realm Roles ***
CreateRealmRole(ctx context.Context, token, realm string, role Role) (string, error)
GetRealmRole(ctx context.Context, token, realm, roleName string) (*Role, error)
GetRealmRoles(ctx context.Context, accessToken, realm string, params GetRoleParams) ([]*Role, error)
GetRealmRoleByID(ctx context.Context, token, realm, roleID string) (*Role, error)
GetRealmRolesByUserID(ctx context.Context, accessToken, realm, userID string) ([]*Role, error)
GetRealmRolesByGroupID(ctx context.Context, accessToken, realm, groupID string) ([]*Role, error)
UpdateRealmRole(ctx context.Context, token, realm, roleName string, role Role) error
UpdateRealmRoleByID(ctx context.Context, token, realm, roleID string, role Role) error
DeleteRealmRole(ctx context.Context, token, realm, roleName string) error
AddRealmRoleToUser(ctx context.Context, token, realm, userID string, roles []Role) error
DeleteRealmRoleFromUser(ctx context.Context, token, realm, userID string, roles []Role) error
AddRealmRoleToGroup(ctx context.Context, token, realm, groupID string, roles []Role) error
DeleteRealmRoleFromGroup(ctx context.Context, token, realm, groupID string, roles []Role) error
AddRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error
DeleteRealmRoleComposite(ctx context.Context, token, realm, roleName string, roles []Role) error
GetCompositeRealmRoles(ctx context.Context, token, realm, roleName string) ([]*Role, error)
GetCompositeRealmRolesByRoleID(ctx context.Context, token, realm, roleID string) ([]*Role, error)
GetCompositeRealmRolesByUserID(ctx context.Context, token, realm, userID string) ([]*Role, error)
GetCompositeRealmRolesByGroupID(ctx context.Context, token, realm, groupID string) ([]*Role, error)
GetAvailableRealmRolesByUserID(ctx context.Context, token, realm, userID string) ([]*Role, error)
GetAvailableRealmRolesByGroupID(ctx context.Context, token, realm, groupID string) ([]*Role, error)
// *** Client Roles ***
AddClientRoleToUser(ctx context.Context, token, realm, idOfClient, userID string, roles []Role) error
AddClientRoleToGroup(ctx context.Context, token, realm, idOfClient, groupID string, roles []Role) error
DeleteClientRoleFromGroup(ctx context.Context, token, realm, idOfClient, groupID string, roles []Role) error
GetCompositeClientRolesByRoleID(ctx context.Context, token, realm, idOfClient, roleID string) ([]*Role, error)
GetClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
GetClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)
GetCompositeClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
GetCompositeClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)
GetAvailableClientRolesByUserID(ctx context.Context, token, realm, idOfClient, userID string) ([]*Role, error)
GetAvailableClientRolesByGroupID(ctx context.Context, token, realm, idOfClient, groupID string) ([]*Role, error)
// *** Realm ***
GetRealm(ctx context.Context, token, realm string) (*RealmRepresentation, error)
GetRealms(ctx context.Context, token string) ([]*RealmRepresentation, error)
CreateRealm(ctx context.Context, token string, realm RealmRepresentation) (string, error)
UpdateRealm(ctx context.Context, token string, realm RealmRepresentation) error
DeleteRealm(ctx context.Context, token, realm string) error
ClearRealmCache(ctx context.Context, token, realm string) error
ClearUserCache(ctx context.Context, token, realm string) error
ClearKeysCache(ctx context.Context, token, realm string) error
GetClientUserSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
GetClientOfflineSessions(ctx context.Context, token, realm, idOfClient string, params ...GetClientUserSessionsParams) ([]*UserSessionRepresentation, error)
GetUserSessions(ctx context.Context, token, realm, userID string) ([]*UserSessionRepresentation, error)
GetUserOfflineSessionsForClient(ctx context.Context, token, realm, userID, idOfClient string) ([]*UserSessionRepresentation, error)
// *** Protection API ***
GetResource(ctx context.Context, token, realm, idOfClient, resourceID string) (*ResourceRepresentation, error)
GetResources(ctx context.Context, token, realm, idOfClient string, params GetResourceParams) ([]*ResourceRepresentation, error)
CreateResource(ctx context.Context, token, realm, idOfClient string, resource ResourceRepresentation) (*ResourceRepresentation, error)
UpdateResource(ctx context.Context, token, realm, idOfClient string, resource ResourceRepresentation) error
DeleteResource(ctx context.Context, token, realm, idOfClient, resourceID string) error
GetResourceClient(ctx context.Context, token, realm, resourceID string) (*ResourceRepresentation, error)
GetResourcesClient(ctx context.Context, token, realm string, params GetResourceParams) ([]*ResourceRepresentation, error)
CreateResourceClient(ctx context.Context, token, realm string, resource ResourceRepresentation) (*ResourceRepresentation, error)
UpdateResourceClient(ctx context.Context, token, realm string, resource ResourceRepresentation) error
DeleteResourceClient(ctx context.Context, token, realm, resourceID string) error
GetScope(ctx context.Context, token, realm, idOfClient, scopeID string) (*ScopeRepresentation, error)
GetScopes(ctx context.Context, token, realm, idOfClient string, params GetScopeParams) ([]*ScopeRepresentation, error)
CreateScope(ctx context.Context, token, realm, idOfClient string, scope ScopeRepresentation) (*ScopeRepresentation, error)
UpdateScope(ctx context.Context, token, realm, idOfClient string, resource ScopeRepresentation) error
DeleteScope(ctx context.Context, token, realm, idOfClient, scopeID string) error
GetPolicy(ctx context.Context, token, realm, idOfClient, policyID string) (*PolicyRepresentation, error)
GetPolicies(ctx context.Context, token, realm, idOfClient string, params GetPolicyParams) ([]*PolicyRepresentation, error)
CreatePolicy(ctx context.Context, token, realm, idOfClient string, policy PolicyRepresentation) (*PolicyRepresentation, error)
UpdatePolicy(ctx context.Context, token, realm, idOfClient string, policy PolicyRepresentation) error
DeletePolicy(ctx context.Context, token, realm, idOfClient, policyID string) error
GetResourcePolicy(ctx context.Context, token, realm, permissionID string) (*ResourcePolicyRepresentation, error)
GetResourcePolicies(ctx context.Context, token, realm string, params GetResourcePoliciesParams) ([]*ResourcePolicyRepresentation, error)
CreateResourcePolicy(ctx context.Context, token, realm, resourceID string, policy ResourcePolicyRepresentation) (*ResourcePolicyRepresentation, error)
UpdateResourcePolicy(ctx context.Context, token, realm, permissionID string, policy ResourcePolicyRepresentation) error
DeleteResourcePolicy(ctx context.Context, token, realm, permissionID string) error
GetPermission(ctx context.Context, token, realm, idOfClient, permissionID string) (*PermissionRepresentation, error)
GetPermissions(ctx context.Context, token, realm, idOfClient string, params GetPermissionParams) ([]*PermissionRepresentation, error)
GetPermissionResources(ctx context.Context, token, realm, idOfClient, permissionID string) ([]*PermissionResource, error)
GetPermissionScopes(ctx context.Context, token, realm, idOfClient, permissionID string) ([]*PermissionScope, error)
GetDependentPermissions(ctx context.Context, token, realm, idOfClient, policyID string) ([]*PermissionRepresentation, error)
CreatePermission(ctx context.Context, token, realm, idOfClient string, permission PermissionRepresentation) (*PermissionRepresentation, error)
UpdatePermission(ctx context.Context, token, realm, idOfClient string, permission PermissionRepresentation) error
DeletePermission(ctx context.Context, token, realm, idOfClient, permissionID string) error
CreatePermissionTicket(ctx context.Context, token, realm string, permissions []CreatePermissionTicketParams) (*PermissionTicketResponseRepresentation, error)
GrantUserPermission(ctx context.Context, token, realm string, permission PermissionGrantParams) (*PermissionGrantResponseRepresentation, error)
UpdateUserPermission(ctx context.Context, token, realm string, permission PermissionGrantParams) (*PermissionGrantResponseRepresentation, error)
GetUserPermissions(ctx context.Context, token, realm string, params GetUserPermissionParams) ([]*PermissionGrantResponseRepresentation, error)
DeleteUserPermission(ctx context.Context, token, realm, ticketID string) error
// *** Credentials API ***
GetCredentialRegistrators(ctx context.Context, token, realm string) ([]string, error)
GetConfiguredUserStorageCredentialTypes(ctx context.Context, token, realm, userID string) ([]string, error)
GetCredentials(ctx context.Context, token, realm, UserID string) ([]*CredentialRepresentation, error)
DeleteCredentials(ctx context.Context, token, realm, UserID, CredentialID string) error
UpdateCredentialUserLabel(ctx context.Context, token, realm, userID, credentialID, userLabel string) error
DisableAllCredentialsByType(ctx context.Context, token, realm, userID string, types []string) error
MoveCredentialBehind(ctx context.Context, token, realm, userID, credentialID, newPreviousCredentialID string) error
MoveCredentialToFirst(ctx context.Context, token, realm, userID, credentialID string) error
// *** Authentication Flows ***
GetAuthenticationFlows(ctx context.Context, token, realm string) ([]*AuthenticationFlowRepresentation, error)
GetAuthenticationFlow(ctx context.Context, token, realm string, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
CreateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation) error
UpdateAuthenticationFlow(ctx context.Context, token, realm string, flow AuthenticationFlowRepresentation, authenticationFlowID string) (*AuthenticationFlowRepresentation, error)
DeleteAuthenticationFlow(ctx context.Context, token, realm, flowID string) error
// *** Identity Providers ***
CreateIdentityProvider(ctx context.Context, token, realm string, providerRep IdentityProviderRepresentation) (string, error)
GetIdentityProvider(ctx context.Context, token, realm, alias string) (*IdentityProviderRepresentation, error)
GetIdentityProviders(ctx context.Context, token, realm string) ([]*IdentityProviderRepresentation, error)
UpdateIdentityProvider(ctx context.Context, token, realm, alias string, providerRep IdentityProviderRepresentation) error
DeleteIdentityProvider(ctx context.Context, token, realm, alias string) error
CreateIdentityProviderMapper(ctx context.Context, token, realm, alias string, mapper IdentityProviderMapper) (string, error)
GetIdentityProviderMapper(ctx context.Context, token string, realm string, alias string, mapperID string) (*IdentityProviderMapper, error)
CreateUserFederatedIdentity(ctx context.Context, token, realm, userID, providerID string, federatedIdentityRep FederatedIdentityRepresentation) error
GetUserFederatedIdentities(ctx context.Context, token, realm, userID string) ([]*FederatedIdentityRepresentation, error)
DeleteUserFederatedIdentity(ctx context.Context, token, realm, userID, providerID string) error
// *** Events API ***
GetEvents(ctx context.Context, token string, realm string, params GetEventsParams) ([]*EventRepresentation, error)
}
```
## Configure gocloak to skip TLS Insecure Verification
```go
client := gocloak.NewClient(serverURL)
restyClient := client.RestyClient()
restyClient.SetDebug(true)
restyClient.SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true })
```
## developing & testing
For local testing you need to start a docker container. Simply run following commands prior to starting the tests:
```shell
docker pull quay.io/keycloak/keycloak
docker run -d \
-e KEYCLOAK_USER=admin \
-e KEYCLOAK_PASSWORD=secret \
-e KEYCLOAK_IMPORT=/tmp/gocloak-realm.json \
-v "`pwd`/testdata/gocloak-realm.json:/tmp/gocloak-realm.json" \
-p 8080:8080 \
--name gocloak-test \
quay.io/keycloak/keycloak:latest -Dkeycloak.profile.feature.upload_scripts=enabled
go test
```
Or you can run with docker compose using the run-tests script
```shell
./run-tests.sh
```
or
```shell
./run-tests.sh <TestCase>
```
Or you can run the tests on you own keycloak:
```shell
export GOCLOAK_TEST_CONFIG=/path/to/gocloak/config.json
```
All resources created as a result of unit tests will be deleted, except for the test user defined in the configuration file.
To remove running docker container after completion of tests:
```shell
docker stop gocloak-test
docker rm gocloak-test
```
### Inspecting custom types
The custom types contain many pointers, so printing them yields mostly pointer values, which aren't much help when debugging your application. For example
```go
someRealmRepresentation := gocloak.RealmRepresentation{
<snip>
}
fmt.Println(someRealmRepresentation)
```
yields a large set of pointer values
```bash
{<nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> 0xc00000e960 <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> 0xc000093cf0 <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> null <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil> <nil>}
```
For convenience, the ```String()``` interface has been added so you can easily see the contents, even for nested custom types. For example,
```go
fmt.Println(someRealmRepresentation.String())
```
yields
```json
{
"clients": [
{
"name": "someClient",
"protocolMappers": [
{
"config": {
"bar": "foo",
"ping": "pong"
},
"name": "someMapper"
}
]
},
{
"name": "AnotherClient"
}
],
"displayName": "someRealm"
}
```
Note that empty parameters are not included, because of the use of ```omitempty``` in the type definitions.
## Examples
* [Add client role to user](./examples/ADD_CLIENT_ROLE_TO_USER.md)
* [Create User Federation & Sync](./examples/USER_FEDERATION.md)
* [Create User Federation & Sync with group ldap mapper](./examples/USER_FEDERATION_GROUP_LDAP_MAPPER.md)
* [Create User Federation & Sync with role ldap mapper](./examples/USER_FEDERATION_ROLE_LDAP_MAPPER.md)
* [Create User Federation & Sync with user attribute ldap mapper](./examples/USER_FEDERATION_USER_ATTRIBUTE_LDAP_MAPPER.md)
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FNerzal%2Fgocloak.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2FNerzal%2Fgocloak?ref=badge_large)
## Related Projects
[GocloakSession](https://github.com/Clarilab/gocloaksession)
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
version: '3'
services:
keycloak:
build: .
command: -Dauto-build -Dfeatures=preview
environment:
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: secret
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: secret
KC_HEALTH_ENABLED: "true"
ports:
- "8080:8080"
healthcheck:
test: curl --fail --silent http://localhost:8080/health/ready 2>&1 || exit 1
interval: 10s
timeout: 10s
retries: 5
volumes:
- ./testdata/gocloak-realm.json:/opt/keycloak/data/import/gocloak-realm.json
entrypoint: ["/opt/keycloak/bin/kc.sh", "start-dev --features=preview --import-realm"]
+38
View File
@@ -0,0 +1,38 @@
package gocloak
import (
"strings"
)
// HTTPErrorResponse is a model of an error response
type HTTPErrorResponse struct {
Error string `json:"error,omitempty"`
Message string `json:"errorMessage,omitempty"`
Description string `json:"error_description,omitempty"`
}
// String returns a string representation of an error
func (e HTTPErrorResponse) String() string {
var res strings.Builder
if len(e.Error) > 0 {
res.WriteString(e.Error)
}
if len(e.Message) > 0 {
if res.Len() > 0 {
res.WriteString(": ")
}
res.WriteString(e.Message)
}
if len(e.Description) > 0 {
if res.Len() > 0 {
res.WriteString(": ")
}
res.WriteString(e.Description)
}
return res.String()
}
// NotEmpty validates that error is not emptyp
func (e HTTPErrorResponse) NotEmpty() bool {
return len(e.Error) > 0 || len(e.Message) > 0 || len(e.Description) > 0
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

File diff suppressed because it is too large Load Diff
+162
View File
@@ -0,0 +1,162 @@
package jwx
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rsa"
"encoding/base64"
"encoding/binary"
"encoding/json"
"fmt"
"math/big"
"strings"
"github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
)
// SignClaims signs the given claims using a given key and a method
func SignClaims(claims jwt.Claims, key interface{}, method jwt.SigningMethod) (string, error) {
token := jwt.NewWithClaims(method, claims)
return token.SignedString(key)
}
// DecodeAccessTokenHeader decodes the header of the accessToken
func DecodeAccessTokenHeader(token string) (*DecodedAccessTokenHeader, error) {
const errMessage = "could not decode access token header"
token = strings.Replace(token, "Bearer ", "", 1)
headerString := strings.Split(token, ".")
decodedData, err := base64.RawStdEncoding.DecodeString(headerString[0])
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
result := &DecodedAccessTokenHeader{}
err = json.Unmarshal(decodedData, result)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
return result, nil
}
func toBigInt(v string) (*big.Int, error) {
decRes, err := base64.RawURLEncoding.DecodeString(v)
if err != nil {
return nil, err
}
res := big.NewInt(0)
res.SetBytes(decRes)
return res, nil
}
var (
curves = map[string]elliptic.Curve{
"P-224": elliptic.P224(),
"P-256": elliptic.P256(),
"P-384": elliptic.P384(),
"P-521": elliptic.P521(),
}
)
func decodeECDSAPublicKey(x, y, crv *string) (*ecdsa.PublicKey, error) {
const errMessage = "could not decode public key"
xInt, err := toBigInt(*x)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
yInt, err := toBigInt(*y)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
var c elliptic.Curve
var ok bool
if c, ok = curves[*crv]; !ok {
return nil, errors.Wrap(fmt.Errorf("unknown curve alg: %s", *crv), errMessage)
}
return &ecdsa.PublicKey{X: xInt, Y: yInt, Curve: c}, nil
}
func decodeRSAPublicKey(e, n *string) (*rsa.PublicKey, error) {
const errMessage = "could not decode public key"
nInt, err := toBigInt(*n)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
decE, err := base64.RawURLEncoding.DecodeString(*e)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
var eBytes []byte
if len(decE) < 8 {
eBytes = make([]byte, 8-len(decE), 8)
eBytes = append(eBytes, decE...)
} else {
eBytes = decE
}
eReader := bytes.NewReader(eBytes)
var eInt uint64
err = binary.Read(eReader, binary.BigEndian, &eInt)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
pKey := rsa.PublicKey{N: nInt, E: int(eInt)}
return &pKey, nil
}
// DecodeAccessTokenRSACustomClaims decodes string access token into jwt.Token
func DecodeAccessTokenRSACustomClaims(accessToken string, e, n *string, customClaims jwt.Claims) (*jwt.Token, error) {
const errMessage = "could not decode accessToken with custom claims"
accessToken = strings.Replace(accessToken, "Bearer ", "", 1)
rsaPublicKey, err := decodeRSAPublicKey(e, n)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
token2, err := jwt.ParseWithClaims(accessToken, customClaims, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return rsaPublicKey, nil
})
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
return token2, nil
}
// DecodeAccessTokenECDSACustomClaims decodes string access token into jwt.Token
func DecodeAccessTokenECDSACustomClaims(accessToken string, x, y, crv *string, customClaims jwt.Claims) (*jwt.Token, error) {
const errMessage = "could not decode accessToken"
accessToken = strings.Replace(accessToken, "Bearer ", "", 1)
publicKey, err := decodeECDSAPublicKey(x, y, crv)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
token2, err := jwt.ParseWithClaims(accessToken, customClaims, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodECDSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return publicKey, nil
})
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
return token2, nil
}
+59
View File
@@ -0,0 +1,59 @@
package jwx
import jwt "github.com/golang-jwt/jwt/v5"
// DecodedAccessTokenHeader is the decoded header from the access token
type DecodedAccessTokenHeader struct {
Alg string `json:"alg"`
Typ string `json:"typ"`
Kid string `json:"kid"`
}
// Claims served by keycloak inside the accessToken
type Claims struct {
jwt.RegisteredClaims
Typ string `json:"typ,omitempty"`
Azp string `json:"azp,omitempty"`
AuthTime int `json:"auth_time,omitempty"`
SessionState string `json:"session_state,omitempty"`
Acr string `json:"acr,omitempty"`
AllowedOrigins []string `json:"allowed-origins,omitempty"`
RealmAccess RealmAccess `json:"realm_access,omitempty"`
ResourceAccess ResourceAccess `json:"resource_access,omitempty"`
Scope string `json:"scope,omitempty"`
EmailVerified bool `json:"email_verified,omitempty"`
Address Address `json:"address,omitempty"`
Name string `json:"name,omitempty"`
PreferredUsername string `json:"preferred_username,omitempty"`
GivenName string `json:"given_name,omitempty"`
FamilyName string `json:"family_name,omitempty"`
Email string `json:"email,omitempty"`
ClientID string `json:"clientId,omitempty"`
ClientHost string `json:"clientHost,omitempty"`
ClientIP string `json:"clientAddress,omitempty"`
}
// Address TODO what fields does any address have?
type Address struct {
}
// RealmAccess holds roles of the user
type RealmAccess struct {
Roles []string `json:"roles,omitempty"`
}
// ResourceAccess holds TODO: What does it hold?
type ResourceAccess struct {
RealmManagement RealmManagement `json:"realm-management,omitempty"`
Account Account `json:"account,omitempty"`
}
// RealmManagement holds TODO: What does it hold?
type RealmManagement struct {
Roles []string `json:"roles,omitempty"`
}
// Account holds TODO: What does it hold?
type Account struct {
Roles []string `json:"roles,omitempty"`
}
+26
View File
@@ -0,0 +1,26 @@
#!/bin/sh
docker-compose down
docker-compose up -d
keycloakServer=http://localhost:8080
url="${keycloakServer}/health"
echo "Checking service availability at $url (CTRL+C to exit)"
while true; do
response=$(curl -s -o /dev/null -w "%{http_code}" $url)
if [ $response -eq 200 ]; then
break
fi
sleep 1
done
echo "Service is now available at ${keycloakServer}"
ARGS=()
if [ $# -gt 0 ]; then
ARGS+=("-run")
ARGS+=("^($@)$")
fi
go test -failfast -race -cover -coverprofile=coverage.out -covermode=atomic -p 10 -cpu 1,2 -bench . -benchmem ${ARGS[@]}
docker-compose down
View File
+14
View File
@@ -0,0 +1,14 @@
package gocloak
// JWT is a JWT
type JWT struct {
AccessToken string `json:"access_token"`
IDToken string `json:"id_token"`
ExpiresIn int `json:"expires_in"`
RefreshExpiresIn int `json:"refresh_expires_in"`
RefreshToken string `json:"refresh_token"`
TokenType string `json:"token_type"`
NotBeforePolicy int `json:"not-before-policy"`
SessionState string `json:"session_state"`
Scope string `json:"scope"`
}
+151
View File
@@ -0,0 +1,151 @@
package gocloak
import (
"context"
"github.com/opentracing/opentracing-go"
)
type contextKey string
var tracerContextKey = contextKey("tracer")
// StringP returns a pointer of a string variable
func StringP(value string) *string {
return &value
}
// PString returns a string value from a pointer
func PString(value *string) string {
if value == nil {
return ""
}
return *value
}
// BoolP returns a pointer of a boolean variable
func BoolP(value bool) *bool {
return &value
}
// PBool returns a boolean value from a pointer
func PBool(value *bool) bool {
if value == nil {
return false
}
return *value
}
// IntP returns a pointer of an integer variable
func IntP(value int) *int {
return &value
}
// Int32P returns a pointer of an int32 variable
func Int32P(value int32) *int32 {
return &value
}
// Int64P returns a pointer of an int64 variable
func Int64P(value int64) *int64 {
return &value
}
// PInt returns an integer value from a pointer
func PInt(value *int) int {
if value == nil {
return 0
}
return *value
}
// PInt32 returns an int32 value from a pointer
func PInt32(value *int32) int32 {
if value == nil {
return 0
}
return *value
}
// PInt64 returns an int64 value from a pointer
func PInt64(value *int64) int64 {
if value == nil {
return 0
}
return *value
}
// Float32P returns a pointer of a float32 variable
func Float32P(value float32) *float32 {
return &value
}
// Float64P returns a pointer of a float64 variable
func Float64P(value float64) *float64 {
return &value
}
// PFloat32 returns an flaot32 value from a pointer
func PFloat32(value *float32) float32 {
if value == nil {
return 0
}
return *value
}
// PFloat64 returns an flaot64 value from a pointer
func PFloat64(value *float64) float64 {
if value == nil {
return 0
}
return *value
}
// NilOrEmpty returns true if string is empty or has a nil value
func NilOrEmpty(value *string) bool {
return value == nil || len(*value) == 0
}
// NilOrEmptyArray returns true if string is empty or has a nil value
func NilOrEmptyArray(value *[]string) bool {
if value == nil || len(*value) == 0 {
return true
}
return (*value)[0] == ""
}
// DecisionStrategyP returns a pointer for a DecisionStrategy value
func DecisionStrategyP(value DecisionStrategy) *DecisionStrategy {
return &value
}
// LogicP returns a pointer for a Logic value
func LogicP(value Logic) *Logic {
return &value
}
// PolicyEnforcementModeP returns a pointer for a PolicyEnforcementMode value
func PolicyEnforcementModeP(value PolicyEnforcementMode) *PolicyEnforcementMode {
return &value
}
// PStringSlice converts a pointer to []string or returns ampty slice if nill value
func PStringSlice(value *[]string) []string {
if value == nil {
return []string{}
}
return *value
}
// NilOrEmptySlice returns true if list is empty or has a nil value
func NilOrEmptySlice(value *[]string) bool {
return value == nil || len(*value) == 0
}
// WithTracer generates a context that has a tracer attached
func WithTracer(ctx context.Context, tracer opentracing.Tracer) context.Context {
return context.WithValue(ctx, tracerContextKey, tracer)
}