Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 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
51 changes: 51 additions & 0 deletions coder-sdk/activity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package coder_test

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"testing"

"github.com/stretchr/testify/require"

"cdr.dev/coder-cli/coder-sdk"
)

func TestPushActivity(t *testing.T) {
t.Parallel()

const source = "test"
const envID = "602d377a-e6b8d763cae7561885c5f1b2"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method, "PushActivity is a POST")
require.Equal(t, "/api/private/metrics/usage/push", r.URL.Path)

expected := map[string]interface{}{
"source": source,
"environment_id": envID,
}
var request map[string]interface{}
err := json.NewDecoder(r.Body).Decode(&request)
require.NoError(t, err, "error decoding JSON")
require.EqualValues(t, expected, request, "unexpected request data")

w.WriteHeader(http.StatusOK)
}))
t.Cleanup(func() {
server.Close()
})

u, err := url.Parse(server.URL)
require.NoError(t, err, "failed to parse test server URL")

client, err := coder.NewClient(coder.ClientOptions{
BaseURL: u,
Token: "SwdcSoq5Jc-0C1r8wfwm7h6h9i0RDk7JT",
})
require.NoError(t, err, "failed to create coder.Client")

err = client.PushActivity(context.Background(), source, envID)
require.NoError(t, err)
}
83 changes: 0 additions & 83 deletions coder-sdk/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,89 +14,6 @@ import (
"cdr.dev/coder-cli/coder-sdk"
)

func TestPushActivity(t *testing.T) {
t.Parallel()

const source = "test"
const envID = "602d377a-e6b8d763cae7561885c5f1b2"
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method, "PushActivity is a POST")
require.Equal(t, "/api/private/metrics/usage/push", r.URL.Path)

expected := map[string]interface{}{
"source": source,
"environment_id": envID,
}
var request map[string]interface{}
err := json.NewDecoder(r.Body).Decode(&request)
require.NoError(t, err, "error decoding JSON")
require.EqualValues(t, expected, request, "unexpected request data")

w.WriteHeader(http.StatusOK)
}))
t.Cleanup(func() {
server.Close()
})

u, err := url.Parse(server.URL)
require.NoError(t, err, "failed to parse test server URL")

client, err := coder.NewClient(coder.ClientOptions{
BaseURL: u,
Token: "SwdcSoq5Jc-0C1r8wfwm7h6h9i0RDk7JT",
})
require.NoError(t, err, "failed to create coder.Client")

err = client.PushActivity(context.Background(), source, envID)
require.NoError(t, err)
}

func TestUsers(t *testing.T) {
t.Parallel()

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method, "Users is a GET")
require.Equal(t, "/api/v0/users", r.URL.Path)

users := []map[string]interface{}{
{
"id": "default",
"email": "root@user.com",
"username": "root",
"name": "Charlie Root",
"roles": []coder.Role{coder.SiteAdmin},
"temporary_password": false,
"login_type": coder.LoginTypeBuiltIn,
"key_regenerated_at": time.Now(),
"created_at": time.Now(),
"updated_at": time.Now(),
},
}

w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(users)
require.NoError(t, err, "error encoding JSON")
}))
t.Cleanup(func() {
server.Close()
})

u, err := url.Parse(server.URL)
require.NoError(t, err, "failed to parse test server URL")

client, err := coder.NewClient(coder.ClientOptions{
BaseURL: u,
Token: "JcmErkJjju-KSrztst0IJX7xGJhKQPtfv",
})
require.NoError(t, err, "failed to create coder.Client")

users, err := client.Users(context.Background())
require.NoError(t, err, "error getting Users")
require.Len(t, users, 1, "users should return a single user")
require.Equal(t, "Charlie Root", users[0].Name)
require.Equal(t, "root", users[0].Username)
}

func TestAuthentication(t *testing.T) {
t.Parallel()

Expand Down
51 changes: 51 additions & 0 deletions coder-sdk/test/login_cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"context"
"fmt"
"net/url"

"cdr.dev/coder-cli/coder-sdk"
)

func main() {
client, err := coder.NewClient(coder.ClientOptions{
BaseURL: &url.URL{
Scheme: "http",
Host: "localhost:8080",
},
Email: "admin",
Password: "vt9g9rxsptrq",
})
if err != nil {
fmt.Printf("login error: %v\n", err)
return
}

user, err := client.Me(context.Background())
if err != nil {
fmt.Printf("Me error: %v\n", err)
return
}

fmt.Printf("user info: %#v\n", user)

fmt.Println("changing password")
err = client.UpdateUser(context.Background(), "me", coder.UpdateUserReq{
UserPasswordSettings: &coder.UserPasswordSettings{
Password: "szbp4q3bcrhc",
},
})
if err != nil {
fmt.Printf("password update error: %v\n", err)
return
}

orgs, err := client.Organizations(context.Background())
if err != nil {
fmt.Printf("org list error: %v\n", err)
return
}

fmt.Printf("orgs info: %#v\n", orgs)
}
23 changes: 22 additions & 1 deletion coder-sdk/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (c *DefaultClient) UserByEmail(ctx context.Context, email string) (*User, e
// UpdateUserReq defines a modification to the user, updating the
// value of all non-nil values.
type UpdateUserReq struct {
// TODO(@cmoog) add update password option
*UserPasswordSettings
Revoked *bool `json:"revoked,omitempty"`
Roles *[]Role `json:"roles,omitempty"`
LoginType *LoginType `json:"login_type,omitempty"`
Expand All @@ -109,6 +109,27 @@ type UpdateUserReq struct {
DotfilesGitURL *string `json:"dotfiles_git_uri,omitempty"`
}

// UserPasswordSettings allows modification of the user's password
// settings.
//
// These settings are only applicable to users managed using the
// built-in authentication provider; users authenticating using
// OAuth must change their password through the identity provider
// instead.
type UserPasswordSettings struct {
// OldPassword is the account's current password.
OldPassword string `json:"old_password,omitempty"`

// Password is the new password, which may be a temporary password.
Password string `json:"password,omitempty"`

// Temporary indicates that API access should be restricted to the
// password change API and a few other APIs. If set to true, Coder
// will prompt the user to change their password upon their next
// login through the web interface.
Temporary bool `json:"temporary_password,omitempty"`
}

// UpdateUser applyes the partial update to the given user.
func (c *DefaultClient) UpdateUser(ctx context.Context, userID string, req UpdateUserReq) error {
return c.requestBody(ctx, http.MethodPatch, "/api/v0/users/"+userID, req, nil)
Expand Down
104 changes: 104 additions & 0 deletions coder-sdk/users_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package coder_test

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"

"github.com/stretchr/testify/require"

"cdr.dev/coder-cli/coder-sdk"
)

func TestUsers(t *testing.T) {
t.Parallel()

server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method, "Users is a GET")
require.Equal(t, "/api/v0/users", r.URL.Path)

users := []map[string]interface{}{
{
"id": "default",
"email": "root@user.com",
"username": "root",
"name": "Charlie Root",
"roles": []coder.Role{coder.SiteAdmin},
"temporary_password": false,
"login_type": coder.LoginTypeBuiltIn,
"key_regenerated_at": time.Now(),
"created_at": time.Now(),
"updated_at": time.Now(),
},
}

w.WriteHeader(http.StatusOK)
err := json.NewEncoder(w).Encode(users)
require.NoError(t, err, "error encoding JSON")
}))
t.Cleanup(func() {
server.Close()
})

u, err := url.Parse(server.URL)
require.NoError(t, err, "failed to parse test server URL")

client, err := coder.NewClient(coder.ClientOptions{
BaseURL: u,
Token: "JcmErkJjju-KSrztst0IJX7xGJhKQPtfv",
})
require.NoError(t, err, "failed to create coder.Client")

users, err := client.Users(context.Background())
require.NoError(t, err, "error getting Users")
require.Len(t, users, 1, "users should return a single user")
require.Equal(t, "Charlie Root", users[0].Name)
require.Equal(t, "root", users[0].Username)
}

func TestUserUpdatePassword(t *testing.T) {
t.Parallel()

server := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPatch, r.Method, "Users is a PATCH")
require.Equal(t, "/api/v0/users/me", r.URL.Path)

expected := map[string]interface{}{
"old_password": "vt9g9rxsptrq",
"password": "wmf39jw2f7pk",
"temporary_password": true,
}
var request map[string]interface{}
err := json.NewDecoder(r.Body).Decode(&request)
require.NoError(t, err, "error decoding JSON")
require.EqualValues(t, expected, request, "unexpected request data")

w.WriteHeader(http.StatusOK)
}))
t.Cleanup(func() {
server.Close()
})

u, err := url.Parse(server.URL)
require.NoError(t, err, "failed to parse test server URL")

client, err := coder.NewClient(coder.ClientOptions{
BaseURL: u,
HTTPClient: server.Client(),
Token: "JcmErkJjju-KSrztst0IJX7xGJhKQPtfv",
})
require.NoError(t, err, "failed to create coder.Client")

err = client.UpdateUser(context.Background(), "me", coder.UpdateUserReq{
UserPasswordSettings: &coder.UserPasswordSettings{
OldPassword: "vt9g9rxsptrq",
Password: "wmf39jw2f7pk",
Temporary: true,
},
})
require.NoError(t, err, "error when updating password")
}