-
Notifications
You must be signed in to change notification settings - Fork 313
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add OpenId client initial access token resource and implement i…
…ts read, create and delete logic test: creating and deleting initial access token
- Loading branch information
Showing
4 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package keycloak | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
) | ||
|
||
type OpenidClientInitialAccessToken struct { | ||
Id string `json:"id,omitempty"` | ||
RealmId string `json:"realm_id"` | ||
Count int `json:"count"` | ||
Expiration int `json:"expiration"` | ||
RemainingCount int `json:"remaining_count"` | ||
Token string `json:"token"` | ||
} | ||
|
||
type OpenidClientInitialAccessTokenCreateModel struct { | ||
Count int `json:"count"` | ||
Expiration int `json:"expiration"` | ||
} | ||
|
||
func (keycloakClient *KeycloakClient) NewOpenidClientInitialAccessToken(ctx context.Context, initialAccessToken *OpenidClientInitialAccessToken) (*OpenidClientInitialAccessToken, error) { | ||
createModel := OpenidClientInitialAccessTokenCreateModel{ | ||
Count: initialAccessToken.Count, | ||
Expiration: initialAccessToken.Expiration, | ||
} | ||
|
||
body, _, err := keycloakClient.post(ctx, fmt.Sprintf("/realms/%s/clients-initial-access", initialAccessToken.RealmId), createModel) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var createdToken OpenidClientInitialAccessToken | ||
conversionErr := json.Unmarshal(body, &createdToken) | ||
if conversionErr != nil { | ||
return nil, conversionErr | ||
} | ||
createdToken.RealmId = initialAccessToken.RealmId | ||
|
||
initialAccessToken.Id = createdToken.Id | ||
initialAccessToken.Token = createdToken.Token | ||
return &createdToken, nil | ||
} | ||
|
||
func (keycloakClient *KeycloakClient) GetClientInitialAccessTokens(ctx context.Context, realmId string) (*[]OpenidClientInitialAccessToken, error) { | ||
|
||
var initialAccessTokens []OpenidClientInitialAccessToken | ||
|
||
err := keycloakClient.get(ctx, fmt.Sprintf("/realms/%s/clients-initial-access", realmId), &initialAccessTokens, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for k := range initialAccessTokens { | ||
initialAccessTokens[k].RealmId = realmId | ||
} | ||
|
||
return &initialAccessTokens, nil | ||
} | ||
|
||
func (keycloakClient *KeycloakClient) GetClientInitialAccessToken(ctx context.Context, realmId, id string) (*OpenidClientInitialAccessToken, error) { | ||
|
||
var initialAccessTokens []OpenidClientInitialAccessToken | ||
|
||
err := keycloakClient.get(ctx, fmt.Sprintf("/realms/%s/clients-initial-access", realmId), &initialAccessTokens, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var token *OpenidClientInitialAccessToken | ||
for k := range initialAccessTokens { | ||
initialAccessTokens[k].RealmId = realmId | ||
if initialAccessTokens[k].Id == id { | ||
token = &initialAccessTokens[k] | ||
} | ||
} | ||
|
||
return token, nil | ||
} | ||
|
||
func (keycloakClient *KeycloakClient) DeleteClientInitialAccessToken(ctx context.Context, realmId, id string) error { | ||
return keycloakClient.delete(ctx, fmt.Sprintf("/realms/%s/clients-initial-access/%s", realmId, id), nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
provider/resource_keycloak_openid_client_initial_access_token.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package provider | ||
|
||
import ( | ||
"context" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/mrparkers/terraform-provider-keycloak/keycloak" | ||
) | ||
|
||
func resourceKeycloakOpenIdClientInitialAccessToken() *schema.Resource { | ||
return &schema.Resource{ | ||
ReadContext: resourceKeycloakOpenIdClientInitialAccessTokenRead, | ||
CreateContext: resourceKeycloakOpenIdClientInitialAccessTokenCreate, | ||
DeleteContext: resourceKeycloakOpenIdClientInitialAccessTokenDelete, | ||
Schema: map[string]*schema.Schema{ | ||
"realm_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"token_count": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"remaining_count": { | ||
Type: schema.TypeInt, | ||
Optional: true, | ||
Computed: true, | ||
}, | ||
"expiration": { | ||
Type: schema.TypeInt, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
"token_value": { | ||
Type: schema.TypeString, | ||
Optional: true, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceKeycloakOpenIdClientInitialAccessTokenRead(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
keycloakClient := meta.(*keycloak.KeycloakClient) | ||
realmId := data.Get("realm_id").(string) | ||
tokens, err := keycloakClient.GetClientInitialAccessTokens(ctx, realmId) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
id := data.Id() | ||
list := *tokens | ||
for i := range list { | ||
if list[i].Id == id { | ||
data.SetId(id) | ||
data.Set("realm_id", list[i].RealmId) | ||
data.Set("token_count", list[i].Count) | ||
data.Set("remaining_count", list[i].RemainingCount) | ||
data.Set("expiration", list[i].Expiration) | ||
data.Set("token_value", list[i].Token) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func resourceKeycloakOpenIdClientInitialAccessTokenCreate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
keycloakClient := meta.(*keycloak.KeycloakClient) | ||
|
||
initialAccessToken := getOpenidClientInitialAccessTokenFromData(data) | ||
createdToken, err := keycloakClient.NewOpenidClientInitialAccessToken(ctx, initialAccessToken) | ||
if err != nil { | ||
return diag.FromErr(err) | ||
} | ||
|
||
data.SetId(createdToken.Id) | ||
data.Set("realm_id", createdToken.RealmId) | ||
data.Set("token_count", createdToken.Count) | ||
data.Set("remaining_count", createdToken.RemainingCount) | ||
data.Set("expiration", createdToken.Expiration) | ||
data.Set("token_value", createdToken.Token) | ||
|
||
return nil | ||
} | ||
|
||
func resourceKeycloakOpenIdClientInitialAccessTokenDelete(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { | ||
keycloakClient := meta.(*keycloak.KeycloakClient) | ||
|
||
realmId := data.Get("realm_id").(string) | ||
id := data.Id() | ||
|
||
return diag.FromErr(keycloakClient.DeleteClientInitialAccessToken(ctx, realmId, id)) | ||
} | ||
|
||
func getOpenidClientInitialAccessTokenFromData(data *schema.ResourceData) *keycloak.OpenidClientInitialAccessToken { | ||
initialAccessToken := &keycloak.OpenidClientInitialAccessToken{ | ||
Id: data.Id(), | ||
RealmId: data.Get("realm_id").(string), | ||
Count: data.Get("token_count").(int), | ||
Expiration: data.Get("expiration").(int), | ||
} | ||
|
||
return initialAccessToken | ||
} |
88 changes: 88 additions & 0 deletions
88
provider/resource_keycloak_openid_client_initial_access_token_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package provider | ||
|
||
import ( | ||
"fmt" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
"github.com/mrparkers/terraform-provider-keycloak/keycloak" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
func TestAccKeycloakOpenidClientsInitialAccessToken_basic(t *testing.T) { | ||
realmName := acctest.RandomWithPrefix("tf-acc") | ||
|
||
resource.Test(t, resource.TestCase{ | ||
ProviderFactories: testAccProviderFactories, | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
CheckDestroy: testAccCheckKeycloakOpenidClientsInitialAccessTokenDestroy(), | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testKeycloakOpenidClientInitialAccessToken_basic(realmName), | ||
Check: testAccCheckOpenidClientInitialAccessTokenExists("keycloak_openid_client_initial_access_token.test_initial_access_token"), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckOpenidClientInitialAccessTokenExists(resourceName string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
_, err := getOpenidClientInitialAccessTokenState(s, resourceName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func getOpenidClientInitialAccessTokenState(s *terraform.State, resourceName string) (*keycloak.OpenidClientInitialAccessToken, error) { | ||
rs, ok := s.RootModule().Resources[resourceName] | ||
if !ok { | ||
return nil, fmt.Errorf("resource not found: %s", resourceName) | ||
} | ||
|
||
realm := rs.Primary.Attributes["realm_id"] | ||
id := rs.Primary.ID | ||
|
||
token, err := keycloakClient.GetClientInitialAccessToken(testCtx, realm, id) | ||
if err != nil { | ||
return nil, fmt.Errorf("error getting realm events config: %s", err) | ||
} | ||
|
||
return token, nil | ||
} | ||
|
||
func testAccCheckKeycloakOpenidClientsInitialAccessTokenDestroy() resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
for name, rs := range s.RootModule().Resources { | ||
if rs.Type != "keycloak_openid_client_initial_access_token" || strings.HasPrefix(name, "data") { | ||
continue | ||
} | ||
|
||
id := rs.Primary.ID | ||
realm := rs.Primary.Attributes["realm_id"] | ||
|
||
role, _ := keycloakClient.GetClientInitialAccessToken(testCtx, realm, id) | ||
if role != nil { | ||
return fmt.Errorf("%s with id %s still exists", name, id) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testKeycloakOpenidClientInitialAccessToken_basic(realm string) string { | ||
return fmt.Sprintf(` | ||
resource "keycloak_realm" "realm" { | ||
realm = "%s" | ||
} | ||
resource "keycloak_openid_client_initial_access_token" "test_initial_access_token" { | ||
realm_id = keycloak_realm.realm.id | ||
token_count = 2 | ||
expiration = 345600 | ||
} | ||
`, realm) | ||
} |