-
Notifications
You must be signed in to change notification settings - Fork 930
feat: Add authentication and personal user endpoint #29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
edad1ca
40be7bd
129a10b
6394949
76a1e75
c652f73
ad85b71
34d898a
54b4576
9c64fd5
323ed6e
962b549
931fd82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package coderdtest | ||
|
||
import ( | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"cdr.dev/slog/sloggers/slogtest" | ||
"github.com/coder/coder/coderd" | ||
"github.com/coder/coder/database" | ||
"github.com/coder/coder/database/databasefake" | ||
) | ||
|
||
type Server struct { | ||
Database database.Store | ||
URL string | ||
} | ||
|
||
func New(t *testing.T) Server { | ||
// This can be hotswapped for a live database instance. | ||
db := databasefake.New() | ||
handler := coderd.New(&coderd.Options{ | ||
Logger: slogtest.Make(t, nil), | ||
Database: db, | ||
}) | ||
srv := httptest.NewServer(handler) | ||
t.Cleanup(srv.Close) | ||
return Server{ | ||
Database: db, | ||
URL: srv.URL, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package coderdtest_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/coder/coder/coderd/coderdtest" | ||
"go.uber.org/goleak" | ||
) | ||
|
||
func TestMain(m *testing.M) { | ||
goleak.VerifyTestMain(m) | ||
} | ||
|
||
func TestNew(t *testing.T) { | ||
_ = coderdtest.New(t) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package coderd | ||
|
||
import ( | ||
"net/http" | ||
"time" | ||
|
||
"github.com/go-chi/render" | ||
|
||
"github.com/coder/coder/database" | ||
"github.com/coder/coder/httpmw" | ||
) | ||
|
||
type User struct { | ||
ID string `json:"id"` | ||
Email string `json:"email"` | ||
CreatedAt time.Time `json:"created_at"` | ||
Username string `json:"username"` | ||
} | ||
|
||
type users struct { | ||
Database database.Store | ||
} | ||
|
||
func (users *users) getAuthenticatedUser(rw http.ResponseWriter, r *http.Request) { | ||
user := httpmw.User(r) | ||
|
||
render.JSON(rw, r, User{ | ||
ID: user.ID, | ||
Email: user.Email, | ||
CreatedAt: user.CreatedAt, | ||
Username: user.Username, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package coderd_test | ||
|
||
import "testing" | ||
|
||
func TestUsers(t *testing.T) { | ||
t.Run("wow", func(t *testing.T) { | ||
|
||
}) | ||
kylecarbs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package databasefake | ||
|
||
import ( | ||
"context" | ||
"database/sql" | ||
|
||
"github.com/coder/coder/database" | ||
) | ||
|
||
// New returns an in-memory fake of the database. | ||
func New() database.Store { | ||
return &fakeQuerier{ | ||
apiKeys: make([]database.APIKey, 0), | ||
users: make([]database.User, 0), | ||
} | ||
} | ||
|
||
type fakeQuerier struct { | ||
apiKeys []database.APIKey | ||
users []database.User | ||
} | ||
|
||
// InTx doesn't rollback data properly for in-memory yet. | ||
func (q *fakeQuerier) InTx(ctx context.Context, fn func(database.Store) error) error { | ||
return fn(q) | ||
} | ||
|
||
func (q *fakeQuerier) GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error) { | ||
for _, apiKey := range q.apiKeys { | ||
if apiKey.ID == id { | ||
return apiKey, nil | ||
} | ||
} | ||
return database.APIKey{}, sql.ErrNoRows | ||
} | ||
|
||
func (q *fakeQuerier) GetUserByID(ctx context.Context, id string) (database.User, error) { | ||
for _, user := range q.users { | ||
if user.ID == id { | ||
return user, nil | ||
} | ||
} | ||
return database.User{}, sql.ErrNoRows | ||
} | ||
|
||
func (q *fakeQuerier) InsertAPIKey(ctx context.Context, arg database.InsertAPIKeyParams) (database.APIKey, error) { | ||
key := database.APIKey{ | ||
ID: arg.ID, | ||
HashedSecret: arg.HashedSecret, | ||
UserID: arg.UserID, | ||
Application: arg.Application, | ||
Name: arg.Name, | ||
LastUsed: arg.LastUsed, | ||
ExpiresAt: arg.ExpiresAt, | ||
CreatedAt: arg.CreatedAt, | ||
UpdatedAt: arg.UpdatedAt, | ||
LoginType: arg.LoginType, | ||
OIDCAccessToken: arg.OIDCAccessToken, | ||
OIDCRefreshToken: arg.OIDCRefreshToken, | ||
OIDCIDToken: arg.OIDCIDToken, | ||
OIDCExpiry: arg.OIDCExpiry, | ||
DevurlToken: arg.DevurlToken, | ||
} | ||
q.apiKeys = append(q.apiKeys, key) | ||
return key, nil | ||
} | ||
|
||
func (q *fakeQuerier) InsertUser(ctx context.Context, arg database.InsertUserParams) (database.User, error) { | ||
user := database.User{ | ||
ID: arg.ID, | ||
Email: arg.Email, | ||
Name: arg.Name, | ||
LoginType: arg.LoginType, | ||
HashedPassword: arg.HashedPassword, | ||
CreatedAt: arg.CreatedAt, | ||
UpdatedAt: arg.UpdatedAt, | ||
Username: arg.Username, | ||
} | ||
q.users = append(q.users, user) | ||
return user, nil | ||
} | ||
|
||
func (q *fakeQuerier) UpdateAPIKeyByID(ctx context.Context, arg database.UpdateAPIKeyByIDParams) error { | ||
for index, apiKey := range q.apiKeys { | ||
if apiKey.ID != arg.ID { | ||
continue | ||
} | ||
apiKey.LastUsed = arg.LastUsed | ||
apiKey.ExpiresAt = arg.ExpiresAt | ||
apiKey.OIDCAccessToken = arg.OIDCAccessToken | ||
apiKey.OIDCRefreshToken = arg.OIDCRefreshToken | ||
apiKey.OIDCExpiry = arg.OIDCExpiry | ||
q.apiKeys[index] = apiKey | ||
return nil | ||
} | ||
return sql.ErrNoRows | ||
} |
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,20 @@ | ||
-- name: ExampleQuery :exec | ||
SELECT 'example query'; | ||
-- name: GetAPIKeyByID :one | ||
SELECT | ||
* | ||
FROM | ||
api_keys | ||
WHERE | ||
id = $1 | ||
LIMIT 1; | ||
|
||
-- name: GetUserByID :one | ||
SELECT * FROM users WHERE id = $1 LIMIT 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this generated code? If so - we should add it to the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope! I'll add a docstring for how this works. |
||
|
||
-- name: InsertAPIKey :one | ||
INSERT INTO api_keys (id, hashed_secret, user_id, application, name, last_used, expires_at, created_at, updated_at, login_type, oidc_access_token, oidc_refresh_token, oidc_id_token, oidc_expiry, devurl_token) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING *; | ||
|
||
-- name: InsertUser :one | ||
INSERT INTO users (id, email, name, login_type, hashed_password, created_at, updated_at, username) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *; | ||
|
||
-- name: UpdateAPIKeyByID :exec | ||
UPDATE api_keys SET last_used = $2, expires_at = $3, oidc_access_token = $4, oidc_refresh_token = $5, oidc_expiry = $6 WHERE id = $1; |
Uh oh!
There was an error while loading. Please reload this page.