Skip to content

Commit

Permalink
Merge pull request #1 from jm-araujo/create/update-users-with-PIN
Browse files Browse the repository at this point in the history
Create/update users with pin
  • Loading branch information
jm-araujo authored Aug 19, 2024
2 parents d2871ff + 5449aeb commit c133c72
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 19 deletions.
1 change: 1 addition & 0 deletions docs/resources/user.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The organization resource allows managing information about a particular Pritunl
- `groups` (List of String) Enter list of groups to allow connections from. Names are case sensitive. If empty all groups will able to connect.
- `mac_addresses` (List of String) Comma separated list of MAC addresses client is allowed to connect from. The validity of the MAC address provided by the VPN client cannot be verified.
- `network_links` (List of String) Network address with cidr subnet. This will provision access to a clients local network to the attached vpn servers and other clients. Multiple networks may be separated by a comma. Router must have a static route to VPN virtual network through client.
- `pin` (String) The PIN code for the user.
- `port_forwarding` (List of Map of String) Comma seperated list of ports to forward using format source_port:dest_port/protocol or start_port-end_port/protocol. Such as 80, 80/tcp, 80:8000/tcp, 1000-2000/udp.

### Read-Only
Expand Down
8 changes: 4 additions & 4 deletions internal/pritunl/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ type Client interface {
DeleteOrganization(name string) error

GetUser(id string, orgId string) (*User, error)
CreateUser(newUser User) (*User, error)
UpdateUser(id string, user *User) error
CreateUser(newUser NewUser) (*User, error)
UpdateUser(id string, user *NewUser) error
DeleteUser(id string, orgId string) error

GetServers() ([]Server, error)
Expand Down Expand Up @@ -693,7 +693,7 @@ func (c client) GetUser(id string, orgId string) (*User, error) {
return &user, nil
}

func (c client) CreateUser(newUser User) (*User, error) {
func (c client) CreateUser(newUser NewUser) (*User, error) {
jsonData, err := json.Marshal(newUser)
if err != nil {
return nil, fmt.Errorf("CreateUser: Error on marshalling data: %s", err)
Expand Down Expand Up @@ -726,7 +726,7 @@ func (c client) CreateUser(newUser User) (*User, error) {
return nil, fmt.Errorf("empty users response")
}

func (c client) UpdateUser(id string, user *User) error {
func (c client) UpdateUser(id string, user *NewUser) error {
jsonData, err := json.Marshal(user)
if err != nil {
return fmt.Errorf("UpdateUser: Error on marshalling data: %s", err)
Expand Down
57 changes: 57 additions & 0 deletions internal/pritunl/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,65 @@ type User struct {
Organization string `json:"organization,omitempty"`
}

type NewUser struct {
ID string `json:"id,omitempty"`
Name string `json:"name"`
Type string `json:"type,omitempty"`
AuthType string `json:"auth_type,omitempty"`
DnsServers []string `json:"dns_servers,omitempty"`
Pin string `json:"pin,omitempty"`
DnsSuffix string `json:"dns_suffix,omitempty"`
DnsMapping string `json:"dns_mapping,omitempty"`
Disabled bool `json:"disabled,omitempty"`
NetworkLinks []string `json:"network_links,omitempty"`
PortForwarding []map[string]interface{} `json:"port_forwarding,omitempty"`
Email string `json:"email,omitempty"`
Status bool `json:"status,omitempty"`
OtpSecret string `json:"otp_secret,omitempty"`
ClientToClient bool `json:"client_to_client,omitempty"`
MacAddresses []string `json:"mac_addresses,omitempty"`
YubicoID string `json:"yubico_id,omitempty"`
SSO interface{} `json:"sso,omitempty"`
BypassSecondary bool `json:"bypass_secondary,omitempty"`
Groups []string `json:"groups,omitempty"`
Audit bool `json:"audit,omitempty"`
Gravatar bool `json:"gravatar,omitempty"`
OtpAuth bool `json:"otp_auth,omitempty"`
DeviceAuth bool `json:"device_auth,omitempty"`
Organization string `json:"organization,omitempty"`
}

type PortForwarding struct {
Dport string `json:"dport"`
Protocol string `json:"protocol"`
Port string `json:"port"`
}

func (user User) ToNewUser() NewUser {
return NewUser{
ID: user.ID,
Name: user.Name,
Type: user.Type,
AuthType: user.AuthType,
DnsServers: user.DnsServers,
DnsSuffix: user.DnsSuffix,
DnsMapping: user.DnsMapping,
Disabled: user.Disabled,
NetworkLinks: user.NetworkLinks,
PortForwarding: user.PortForwarding,
Email: user.Email,
Status: user.Status,
OtpSecret: user.OtpSecret,
ClientToClient: user.ClientToClient,
MacAddresses: user.MacAddresses,
YubicoID: user.YubicoID,
SSO: user.SSO,
BypassSecondary: user.BypassSecondary,
Groups: user.Groups,
Audit: user.Audit,
Gravatar: user.Gravatar,
OtpAuth: user.OtpAuth,
DeviceAuth: user.DeviceAuth,
Organization: user.Organization,
}
}
45 changes: 30 additions & 15 deletions internal/provider/resource_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ func resourceUser() *schema.Resource {
Optional: true,
Description: "Bypass secondary authentication such as the PIN and two-factor authentication. Use for server users that can't provide a two-factor code.",
},
"pin": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
Description: "The PIN for user authentication.",
},
},
CreateContext: resourceUserCreate,
ReadContext: resourceUserRead,
Expand Down Expand Up @@ -170,80 +176,88 @@ func resourceUserUpdate(ctx context.Context, d *schema.ResourceData, meta interf
return diag.FromErr(err)
}

updatedUser := user.ToNewUser()

if d.HasChange("pin") {
if v, ok := d.GetOk("pin"); ok {
updatedUser.Pin = v.(string)
}
}

if v, ok := d.GetOk("name"); ok {
user.Name = v.(string)
updatedUser.Name = v.(string)
}

if v, ok := d.GetOk("organization_id"); ok {
user.Organization = v.(string)
updatedUser.Organization = v.(string)
}

if d.HasChange("groups") {
groups := make([]string, 0)
for _, v := range d.Get("groups").([]interface{}) {
groups = append(groups, v.(string))
}
user.Groups = groups
updatedUser.Groups = groups
}

if v, ok := d.GetOk("email"); ok {
user.Email = v.(string)
updatedUser.Email = v.(string)
}

// TODO: Fixme
if v, ok := d.GetOk("disabled"); ok {
user.Disabled = v.(bool)
updatedUser.Disabled = v.(bool)
}

if d.HasChange("port_forwarding") {
portForwarding := make([]map[string]interface{}, 0)
for _, v := range d.Get("port_forwarding").([]interface{}) {
portForwarding = append(portForwarding, v.(map[string]interface{}))
}
user.PortForwarding = portForwarding
updatedUser.PortForwarding = portForwarding
}

if d.HasChange("network_links") {
networkLinks := make([]string, 0)
for _, v := range d.Get("network_links").([]interface{}) {
networkLinks = append(networkLinks, v.(string))
}
user.NetworkLinks = networkLinks
updatedUser.NetworkLinks = networkLinks
}

if v, ok := d.GetOk("client_to_client"); ok {
user.ClientToClient = v.(bool)
updatedUser.ClientToClient = v.(bool)
}

if v, ok := d.GetOk("auth_type"); ok {
user.AuthType = v.(string)
updatedUser.AuthType = v.(string)
}

if d.HasChange("mac_addresses") {
macAddresses := make([]string, 0)
for _, v := range d.Get("mac_addresses").([]interface{}) {
macAddresses = append(macAddresses, v.(string))
}
user.MacAddresses = macAddresses
updatedUser.MacAddresses = macAddresses
}

if d.HasChange("dns_servers") {
dnsServers := make([]string, 0)
for _, v := range d.Get("dns_servers").([]interface{}) {
dnsServers = append(dnsServers, v.(string))
}
user.DnsServers = dnsServers
updatedUser.DnsServers = dnsServers
}

if v, ok := d.GetOk("dns_suffix"); ok {
user.DnsSuffix = v.(string)
updatedUser.DnsSuffix = v.(string)
}

if v, ok := d.GetOk("bypass_secondary"); ok {
user.BypassSecondary = v.(bool)
updatedUser.BypassSecondary = v.(bool)
}

err = apiClient.UpdateUser(d.Id(), user)
err = apiClient.UpdateUser(d.Id(), &updatedUser)
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -279,7 +293,7 @@ func resourceUserCreate(_ context.Context, d *schema.ResourceData, meta interfac
groups = append(groups, v.(string))
}

userData := pritunl.User{
userData := pritunl.NewUser{
Name: d.Get("name").(string),
Organization: d.Get("organization_id").(string),
AuthType: d.Get("auth_type").(string),
Expand All @@ -293,6 +307,7 @@ func resourceUserCreate(_ context.Context, d *schema.ResourceData, meta interfac
MacAddresses: macAddresses,
BypassSecondary: d.Get("bypass_secondary").(bool),
Groups: groups,
Pin: d.Get("pin").(string),
}

user, err := apiClient.CreateUser(userData)
Expand Down

0 comments on commit c133c72

Please sign in to comment.