Skip to content
This repository was archived by the owner on Jun 30, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.8.1
github.com/hashicorp/terraform-plugin-sdk/v2 v2.16.0
github.com/mitchellh/go-homedir v1.1.0
github.com/sethvargo/go-password v0.2.0
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
google.golang.org/api v0.79.0
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sethvargo/go-password v0.2.0 h1:BTDl4CC/gjf/axHMaDQtw507ogrXLci6XRiLc7i/UHI=
github.com/sethvargo/go-password v0.2.0/go.mod h1:Ym4Mr9JXLBycr02MFuVQ/0JHidNetSgbzutTr3zsYXE=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
Expand Down
34 changes: 15 additions & 19 deletions internal/provider/resource_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"log"
"math/rand"
"net/mail"
"reflect"
"strconv"
Expand All @@ -14,6 +15,8 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"github.com/sethvargo/go-password/password"

directory "google.golang.org/api/admin/directory/v1"
"google.golang.org/api/googleapi"
)
Expand Down Expand Up @@ -146,7 +149,7 @@ func resourceUser() *schema.Resource {
Description: "Stores the password for the user account. A password can contain any combination of " +
"ASCII characters. A minimum of 8 characters is required. The maximum length is 100 characters. " +
"As the API does not return the value of password, this field is write-only, and the value stored " +
"in the state will be what is provided in the configuration. The field is required on create and will " +
"in the state will be what is provided in the configuration. If the field is not set on create a random password will be generated " +
"be empty on import.",
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -1003,17 +1006,16 @@ func resourceUser() *schema.Resource {

func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var diags diag.Diagnostics

var generated_password string
// use the meta value to retrieve your client from the provider configure method
client := meta.(*apiClient)

generated_password = ""
if d.Get("password").(string) == "" {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: fmt.Sprintf("Password is required when creating a new user"),
})

return diags
// generate password
generated_password, _ = password.Generate(rand.Intn(64)+8, 4, 4, false, true)
log.Printf("[DEBUG] Auto Generating password for User %q", d.Id())
} else {
generated_password = d.Get("password").(string)
}

primaryEmail := d.Get("primary_email").(string)
Expand All @@ -1031,7 +1033,7 @@ func resourceUserCreate(ctx context.Context, d *schema.ResourceData, meta interf

userObj := directory.User{
PrimaryEmail: primaryEmail,
Password: d.Get("password").(string),
Password: generated_password,
HashFunction: d.Get("hash_function").(string),
Suspended: d.Get("suspended").(bool),
ChangePasswordAtNextLogin: d.Get("change_password_at_next_login").(bool),
Expand Down Expand Up @@ -1240,21 +1242,15 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
if d.HasChange("primary_email") {
userObj.PrimaryEmail = primaryEmail
}

if d.HasChange("password") {
userObj.Password = d.Get("password").(string)

if userObj.Password == "" {
forceSendFields = append(forceSendFields, "Password")
if d.Get("password").(string) != "" {
if d.HasChange("password") {
userObj.Password = d.Get("password").(string)
}
}

if d.HasChange("hash_function") {
userObj.HashFunction = d.Get("hash_function").(string)

if userObj.HashFunction == "" {
forceSendFields = append(forceSendFields, "HashFunction")
}
}

if d.HasChange("org_unit_path") {
Expand Down
18 changes: 16 additions & 2 deletions internal/provider/resource_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,22 @@ func TestAccResourceUser_noPassword(t *testing.T) {
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceUser_noPassword(testUserVals),
ExpectError: regexp.MustCompile("Password is required"),
Config: testAccResourceUser_noPassword(testUserVals),
},
{
ResourceName: "googleworkspace_user.my-new-user",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"etag", "password", "hash_function"},
},
{
Config: testAccResourceUser_noPassword(testUserVals),
},
{
ResourceName: "googleworkspace_user.my-new-user",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"etag", "password", "hash_function"},
},
},
})
Expand Down