Skip to content

Commit

Permalink
fix(ReplaceResource): Use reflection to unmarshal to a zero-value res…
Browse files Browse the repository at this point in the history
…ource to avoid issues with non-returned fields

Hopefully will fix PennState#58
  • Loading branch information
nabowler committed Jun 30, 2021
1 parent 46947f6 commit 2ad6452
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion pkg/scim/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,30 @@ func (c Client) ReplaceResource(ctx context.Context, res Resource) error {
return errors.New(resp.Status)
}

return json.Unmarshal(body, res)
// get the value of the generic resource
vRes := reflect.ValueOf(res)

// if the code below can't set the value properly, default to the original behavior
// I suspect this can't be true since Resource is an interface, but I don't have
// enough reflection experience to make that guarantee.
// The kind checks are to prevent vRes.Elem() from panicking.
if (vRes.Kind() != reflect.Ptr && vRes.Kind() != reflect.Interface) || !vRes.Elem().CanSet() {
return json.Unmarshal(body, res)
}

// create a pointer to a zero-value resource of the same Resource implementation type
unmarshalledRes := reflect.New(reflect.Indirect(vRes).Type())

// unmarshal the response to the zero-value resource
err = json.Unmarshal(body, unmarshalledRes.Interface())
if err != nil {
return err
}

// replace the original resource with the unmarshalled value
vRes.Elem().Set(reflect.Indirect(unmarshalledRes))

return nil
}

//
Expand Down

0 comments on commit 2ad6452

Please sign in to comment.