Skip to content

Commit

Permalink
Merge pull request #33 from BuoyantIO/flynn/user-support
Browse files Browse the repository at this point in the history
Maintain the "logged in" user directly in Faces
  • Loading branch information
kflynn authored Oct 29, 2024
2 parents bd3ffeb + 57c43e6 commit 99fab62
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 30 deletions.
53 changes: 30 additions & 23 deletions assets/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,9 @@ <H1>Faces</H1>
<input id="btnToggle" type="button" value="Init..." class="roundedButton margins" />
<input id="btnCounters" type="button" value="Init..." class="roundedButton margins" />
<input id="btnShowPods" type="button" value="Init..." class="roundedButton margins" />
<div id="userDiv" class="inline margins"></div>
<div id="userDiv" class="inline margins">
User: <input id="userName" contenteditable="true" placeholder="unknown"></span>
</div>

<div id="timer" class="inline margins"></div>

Expand Down Expand Up @@ -329,28 +331,38 @@ <H1>Faces</H1>
// UserController is a class to (totally insecurely) manage the username.

class UserController {
constructor(logger, userDiv, initialUser, onchange) {
this.userDiv = userDiv // not an ID, the div itself
// this.button.onclick = () => { this.toggle() }
this.user = initialUser
this.start()
}
constructor(logger, userDiv, userInput, initialUser) {
this.logger = logger;
this.logger.info("Starting UserController")
this.userDiv = userDiv; // not an ID, the div itself
this.userInput = userInput; // not an ID, the element itself
this.userInput.addEventListener("keydown",
(event) => {
this.keydownHandler(event)
}
);

start() {
let color = "#000000";
this.start(initialUser)
}

if (this.user == "unknown") {
color = Cell.colors.grey;
keydownHandler(event) {
if (event.key === "Enter") {
event.preventDefault();
this.updateUser(this.userInput.value.trim());
}
}

updateUser(user) {
this.user = user;
this.logger.info(`User: ${this.user}`);

this.userDiv.innerHTML = `<span style="color:${color}">User: ${this.user}</span>`
this.userInput.value = this.user;
this.userInput.blur();
}

// stop() {
// this.active = false
// this.button.value = this.stopLabel
// this.onstop()
// }
start(initialUser) {
this.updateUser(initialUser);
}
}

//////// CounterSwitch
Expand Down Expand Up @@ -1216,12 +1228,7 @@ <H1>Faces</H1>
logger.info(`Page loaded; user ${initialUser}`)
logger.info(`User-Agent: %%{user_agent}`)

let userControl = new UserController(
logger, $("userDiv"), initialUser,
(user) => {
logger.info(`User changed to ${user}`)
}
)
let userControl = new UserController(logger, $("userDiv"), $("userName"), initialUser)

let sw = new StartStop($("btnToggle"), userControl)

Expand Down
26 changes: 24 additions & 2 deletions cmd/generic/color/color.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/BuoyantIO/faces-demo/v2/pkg/faces"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)

Expand All @@ -45,9 +46,17 @@ type colorServer struct {
}

func (srv *colorServer) Center(ctx context.Context, req *faces.ColorRequest) (*faces.ColorResponse, error) {
md, ok := metadata.FromIncomingContext(ctx)

if !ok {
return nil, status.Errorf(codes.DataLoss, "failed to get metadata")
}

user := md.Get("user")

baseResp := srv.provider.Get(int(req.Row), int(req.Column))

slog.Debug(fmt.Sprintf("CENTER: %d, %d => %d, %s\n", req.Row, req.Column, baseResp.StatusCode, baseResp.Body))
slog.Debug(fmt.Sprintf("CENTER: %d, %d (%s) => %d, %s\n", req.Row, req.Column, user, baseResp.StatusCode, baseResp.Body))

switch baseResp.StatusCode {
case http.StatusOK:
Expand All @@ -66,9 +75,22 @@ func (srv *colorServer) Center(ctx context.Context, req *faces.ColorRequest) (*f
}

func (srv *colorServer) Edge(ctx context.Context, req *faces.ColorRequest) (*faces.ColorResponse, error) {
md, ok := metadata.FromIncomingContext(ctx)

if !ok {
return nil, status.Errorf(codes.DataLoss, "failed to get metadata")
}

user := ""
users := md.Get("x-faces-user")

if len(users) > 0 {
user = users[0]
}

baseResp := srv.provider.Get(int(req.Row), int(req.Column))

slog.Debug(fmt.Sprintf("EDGE: %d, %d => %d, %s\n", req.Row, req.Column, baseResp.StatusCode, baseResp.Body))
slog.Debug(fmt.Sprintf("EDGE: %d, %d (%s) => %d, %s\n", req.Row, req.Column, user, baseResp.StatusCode, baseResp.Body))

switch baseResp.StatusCode {
case http.StatusOK:
Expand Down
10 changes: 8 additions & 2 deletions pkg/faces/faceserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/BuoyantIO/faces-demo/v2/pkg/utils"
grpc "google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
)

type FaceServer struct {
Expand Down Expand Up @@ -287,6 +288,11 @@ func (srv *FaceServer) faceGetHandler(r *http.Request, rstat *BaseRequestStatus)
defer conn.Close()

client := NewColorServiceClient(conn)

// Anything linked to this variable will transmit request headers.
md := metadata.New(map[string]string{"x-faces-user": user})
ctx := metadata.NewOutgoingContext(context.Background(), md)

colorReq := &ColorRequest{
Row: int32(row),
Column: int32(column),
Expand All @@ -300,9 +306,9 @@ func (srv *FaceServer) faceGetHandler(r *http.Request, rstat *BaseRequestStatus)
}

if subrequest == "center" {
colorResp, err = client.Center(context.Background(), colorReq)
colorResp, err = client.Center(ctx, colorReq)
} else {
colorResp, err = client.Edge(context.Background(), colorReq)
colorResp, err = client.Edge(ctx, colorReq)
}

if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions pkg/faces/guiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf(" userHeaderName: %s\n", srv.userHeaderName)
fmt.Printf(" headers: %s\n", r.Header)

// Default user comes from the header value used to load the GUI, which
// might be "".
user := r.Header.Get(srv.userHeaderName)
if user == "" {
user = "unknown"
}

userAgent := r.Header.Get("User-Agent")
if userAgent == "" {
userAgent = "unknown"
Expand Down

0 comments on commit 99fab62

Please sign in to comment.