Skip to content

Commit

Permalink
Warning for userclient/machineclient if client has any nonapproved sc…
Browse files Browse the repository at this point in the history
…opes
  • Loading branch information
joachimhalvorsen authored Sep 25, 2024
1 parent 85e5604 commit d97985e
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 61 deletions.
2 changes: 2 additions & 0 deletions internal/elvidapiclient/dtos.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type UserClientDto struct {
OneTimeUsageForRefreshTokens bool `json:"OneTimeUsageForRefreshTokens"`
RefreshTokensLifeTime int `json:"RefreshTokensLifeTime"`
ClientProperties []ClientPropertyDto `json:"ClientProperties"`
IsAllScopesApproved bool `json:"IsAllScopesApproved"`
}

type ClientPropertyDto struct {
Expand All @@ -42,6 +43,7 @@ type MachineClientDto struct {
AccessTokenLifeTime int `json:"AccessTokenLifeTime"`
Scopes []string `json:"Scopes"`
ClientClaims []ClientClaimDto `json:"ClientClaims"`
IsAllScopesApproved bool `json:"IsAllScopesApproved"`
}

type ClientClaimDto struct {
Expand Down
52 changes: 21 additions & 31 deletions internal/elvidapiclient/machineclientservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
)

func CreateMachineClient(ctx context.Context, elvidAuthority string, accessTokenAD string, machineClientInput *MachineClientDto) (*MachineClientDto, error) {
Expand All @@ -22,16 +23,7 @@ func CreateMachineClient(ctx context.Context, elvidAuthority string, accessToken
return nil, ElvidErrorResponse(response, apiUrl)
}

data, _ := io.ReadAll(response.Body)
defer response.Body.Close()

var machineClient MachineClientDto
err = json.Unmarshal(data, &machineClient)
if err != nil {
return nil, err
}

return &machineClient, nil
return responseAsMachineClientDto(response)
}

func ReadMachineClient(ctx context.Context, elvidAuthority string, accessTokenAD string, id string) (*MachineClientDto, error) {
Expand All @@ -51,16 +43,7 @@ func ReadMachineClient(ctx context.Context, elvidAuthority string, accessTokenAD
return nil, ElvidErrorResponse(response, apiUrl)
}

data, _ := io.ReadAll(response.Body)
defer response.Body.Close()

var machineClient MachineClientDto
err = json.Unmarshal(data, &machineClient)
if err != nil {
return nil, err
}

return &machineClient, nil
return responseAsMachineClientDto(response)
}

func UpdateMachineClient(ctx context.Context, elvidAuthority string, accessTokenAD string, machineClient *MachineClientDto) (*MachineClientDto, error) {
Expand All @@ -69,7 +52,6 @@ func UpdateMachineClient(ctx context.Context, elvidAuthority string, accessToken
machineClientAsJson, _ := json.Marshal(machineClient)

response, err := PatchRequest(ctx, apiUrl, accessTokenAD, machineClientAsJson)

if err != nil {
return nil, err
}
Expand All @@ -78,16 +60,7 @@ func UpdateMachineClient(ctx context.Context, elvidAuthority string, accessToken
return nil, ElvidErrorResponse(response, apiUrl)
}

data, _ := io.ReadAll(response.Body)
defer response.Body.Close()

var machineClientResponse MachineClientDto
err = json.Unmarshal(data, &machineClient)
if err != nil {
return nil, err
}

return &machineClientResponse, nil
return responseAsMachineClientDto(response)
}

func DeleteMachineClient(ctx context.Context, elvidAuthority string, accessTokenAD string, id string) error {
Expand All @@ -105,3 +78,20 @@ func DeleteMachineClient(ctx context.Context, elvidAuthority string, accessToken

return nil
}

func responseAsMachineClientDto(response *http.Response) (*MachineClientDto, error) {
data, readErr := io.ReadAll(response.Body)
defer response.Body.Close()

if readErr != nil {
return nil, readErr
}

var machineClientResponseDto MachineClientDto
err := json.Unmarshal(data, &machineClientResponseDto)
if err != nil {
return nil, err
}

return &machineClientResponseDto, nil
}
47 changes: 23 additions & 24 deletions internal/elvidapiclient/userclientservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"io"
"net/http"
)

func CreateUserClient(ctx context.Context, elvidAuthority string, accessTokenAD string, userClient *UserClientDto) (*UserClientDto, error) {
Expand All @@ -20,16 +21,7 @@ func CreateUserClient(ctx context.Context, elvidAuthority string, accessTokenAD
return nil, ElvidErrorResponse(response, apiUrl)
}

data, _ := io.ReadAll(response.Body)
defer response.Body.Close()

var createdUserClient UserClientDto
err = json.Unmarshal(data, &createdUserClient)
if err != nil {
return nil, err
}

return &createdUserClient, nil
return responseAsUserClientDto(response)
}

func ReadUserClient(ctx context.Context, elvidAuthority string, accessTokenAD string, id string) (*UserClientDto, error) {
Expand All @@ -49,33 +41,24 @@ func ReadUserClient(ctx context.Context, elvidAuthority string, accessTokenAD st
return nil, ElvidErrorResponse(response, apiUrl)
}

data, _ := io.ReadAll(response.Body)
defer response.Body.Close()

var userClient UserClientDto
err = json.Unmarshal(data, &userClient)
if err != nil {
return nil, err
}

return &userClient, nil
return responseAsUserClientDto(response)
}

func UpdateUserClient(ctx context.Context, elvidAuthority string, accessTokenAD string, userClient *UserClientDto) error {
func UpdateUserClient(ctx context.Context, elvidAuthority string, accessTokenAD string, userClient *UserClientDto) (*UserClientDto, error) {
apiUrl := fmt.Sprintf("%s/api/userclient", elvidAuthority)

userClientAsJson, _ := json.Marshal(userClient)
response, err := PatchRequest(ctx, apiUrl, accessTokenAD, userClientAsJson)

if err != nil {
return err
return nil, err
}

if response.StatusCode != 200 {
return ElvidErrorResponse(response, apiUrl)
return nil, ElvidErrorResponse(response, apiUrl)
}

return nil
return responseAsUserClientDto(response)
}

func DeleteUserClient(ctx context.Context, elvidAuthority string, accessTokenAD string, id string) error {
Expand All @@ -93,3 +76,19 @@ func DeleteUserClient(ctx context.Context, elvidAuthority string, accessTokenAD

return nil
}

func responseAsUserClientDto(response *http.Response) (*UserClientDto, error) {
data, readErr := io.ReadAll(response.Body)
defer response.Body.Close()
if readErr != nil {
return nil, readErr
}

var userClientResponseDto UserClientDto
err := json.Unmarshal(data, &userClientResponseDto)
if err != nil {
return nil, err
}

return &userClientResponseDto, nil
}
4 changes: 4 additions & 0 deletions internal/provider/provider_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ func convertStringArrayToSet(array []string) types.Set {

return set
}

func MissingScopeApprovalWarning(id string, clientName string) string {
return "Scope approval is missing for " + clientName + ". Please request scope approval in the #core-henvendelser channel on Slack. For more information about this client, visit: " + providerInput.ElvIDAuthority + "/Configuration/ClientDetails?client_Id=" + id
}
19 changes: 18 additions & 1 deletion internal/provider/resource_machineclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package provider

import (
"context"
"encoding/json"
"strconv"

"github.com/3lvia/terraform-provider-elvid/internal/elvidapiclient"
Expand All @@ -14,6 +15,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

func MachineClientResourceSetup() resource.Resource {
Expand Down Expand Up @@ -133,6 +135,10 @@ func (r *MachineClientResource) Create(ctx context.Context, req resource.CreateR
plan.ClientId = types.StringValue(machineClientResponseDto.ClientId)
plan.TokenEndpoint = types.StringValue(providerInput.ElvIDAuthority + "/connect/token")

if !machineClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(strconv.Itoa(machineClientResponseDto.Id), machineClientResponseDto.ClientName), "During Create")
}

diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
Expand All @@ -156,6 +162,10 @@ func (r *MachineClientResource) Read(ctx context.Context, req resource.ReadReque
return
}

if !machineClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(state.Id.ValueString(), machineClientResponseDto.ClientName), "During Read")
}

state.MachineClientResourceFromDto(machineClientResponseDto)
diags = resp.State.Set(ctx, state)
resp.Diagnostics.Append(diags...)
Expand All @@ -176,12 +186,19 @@ func (r *MachineClientResource) Update(ctx context.Context, req resource.UpdateR

machineClientRequestDto.Id, _ = strconv.Atoi(plan.Id.ValueString())

_, err := elvidapiclient.UpdateMachineClient(ctx, providerInput.ElvIDAuthority, providerInput.AccessTokenAD, machineClientRequestDto)
machineClientResponseDto, err := elvidapiclient.UpdateMachineClient(ctx, providerInput.ElvIDAuthority, providerInput.AccessTokenAD, machineClientRequestDto)
if err != nil {
resp.Diagnostics.AddError("Updating machineclient resulted in an error", err.Error())
return
}

serialized, _ := json.Marshal(machineClientResponseDto)
tflog.Error(ctx, "During update machineClientResponseDto: "+string(serialized))

if !machineClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(plan.Id.ValueString(), machineClientResponseDto.ClientName), "During Update")
}

plan.TokenEndpoint = types.StringValue(providerInput.ElvIDAuthority + "/connect/token")
diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
Expand Down
14 changes: 13 additions & 1 deletion internal/provider/resource_userclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ func (r *UserClientResource) Create(ctx context.Context, req resource.CreateRequ
plan.Id = types.StringValue(strconv.Itoa(userClientResponseDto.Id))
plan.ClientId = types.StringValue(userClientResponseDto.ClientId)

if !userClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(strconv.Itoa(userClientResponseDto.Id), userClientResponseDto.ClientName), "")
}

diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
Expand All @@ -206,6 +210,10 @@ func (r *UserClientResource) Read(ctx context.Context, req resource.ReadRequest,
return
}

if !userClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(state.Id.ValueString(), userClientResponseDto.ClientName), "")
}

state.UserClientResourceFromDto(userClientResponseDto)
diags = resp.State.Set(ctx, state)
resp.Diagnostics.Append(diags...)
Expand All @@ -222,12 +230,16 @@ func (r *UserClientResource) Update(ctx context.Context, req resource.UpdateRequ
userClientRequestDto := plan.DtoFromUserClientResource(diags)
userClientRequestDto.Id, _ = strconv.Atoi(plan.Id.ValueString())

err := elvidapiclient.UpdateUserClient(ctx, providerInput.ElvIDAuthority, providerInput.AccessTokenAD, userClientRequestDto)
userClientResponseDto, err := elvidapiclient.UpdateUserClient(ctx, providerInput.ElvIDAuthority, providerInput.AccessTokenAD, userClientRequestDto)
if err != nil {
resp.Diagnostics.AddError("Updating userclient resulted in an error", err.Error())
return
}

if !userClientResponseDto.IsAllScopesApproved {
resp.Diagnostics.AddWarning(MissingScopeApprovalWarning(plan.Id.ValueString(), userClientResponseDto.ClientName), "")
}

diags = resp.State.Set(ctx, plan)
resp.Diagnostics.Append(diags...)
}
Expand Down
8 changes: 4 additions & 4 deletions terraform-tester.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ provider "elvid" {
terraform_sp_client_id = var.terraform_sp_client_id
terraform_sp_client_secret = var.terraform_sp_client_secret
environment = var.environment
#override_elvid_authority = "https://localhost:44383"
override_elvid_authority = "https://elvid.dev-elvia.io"
override_elvid_authority = "https://localhost:44383"
#override_elvid_authority = "https://elvid.dev-elvia.io"
run_hashed_secret_validation = true
}

Expand Down Expand Up @@ -55,9 +55,9 @@ provider "vault" {
## Machine client

# resource "elvid_machineclient" "machineclient10" {
# name = "2024-09-16"
# name = "2024-09-23"
# test_user_login_enabled = true
# access_token_life_time = 3512
# access_token_life_time = 3522
# scopes = ["elvid.verifydeployment", "louvre.imageapi"]
# resource_taint_version = "5"
# # client_claims {
Expand Down

0 comments on commit d97985e

Please sign in to comment.