mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-11 07:12:59 +02:00
authenticate: update user info dashboard to show group info for enterprise (#3736)
* authenticate: update user info dashboard to show group info for enterprise * Update ui/src/components/GroupDetails.tsx Co-authored-by: bobby <1544881+desimone@users.noreply.github.com> Co-authored-by: bobby <1544881+desimone@users.noreply.github.com>
This commit is contained in:
parent
45ce6f693a
commit
2b319822a4
8 changed files with 118 additions and 26 deletions
|
@ -17,6 +17,7 @@ import (
|
|||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/pomerium/csrf"
|
||||
"github.com/pomerium/datasource/pkg/directory"
|
||||
"github.com/pomerium/pomerium/authenticate/handlers"
|
||||
"github.com/pomerium/pomerium/authenticate/handlers/webauthn"
|
||||
"github.com/pomerium/pomerium/internal/httputil"
|
||||
|
@ -545,7 +546,7 @@ func (a *Authenticate) getUserInfoData(r *http.Request) (handlers.UserInfoData,
|
|||
}
|
||||
creationOptions, requestOptions, _ := a.webauthn.GetOptions(r.Context())
|
||||
|
||||
return handlers.UserInfoData{
|
||||
data := handlers.UserInfoData{
|
||||
CSRFToken: csrf.Token(r),
|
||||
IsImpersonated: isImpersonated,
|
||||
Session: pbSession,
|
||||
|
@ -556,7 +557,33 @@ func (a *Authenticate) getUserInfoData(r *http.Request) (handlers.UserInfoData,
|
|||
WebAuthnURL: urlutil.WebAuthnURL(r, authenticateURL, state.sharedKey, r.URL.Query()),
|
||||
|
||||
BrandingOptions: a.options.Load().BrandingOptions,
|
||||
}, nil
|
||||
}
|
||||
a.fillEnterpriseUserInfoData(r.Context(), &data, pbSession.GetUserId())
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (a *Authenticate) fillEnterpriseUserInfoData(
|
||||
ctx context.Context,
|
||||
dst *handlers.UserInfoData,
|
||||
userID string,
|
||||
) {
|
||||
client := a.state.Load().dataBrokerClient
|
||||
|
||||
res, _ := client.Get(ctx, &databroker.GetRequest{Type: "type.googleapis.com/pomerium.config.Config", Id: "dashboard"})
|
||||
dst.IsEnterprise = res.GetRecord() != nil
|
||||
if !dst.IsEnterprise {
|
||||
return
|
||||
}
|
||||
|
||||
dst.DirectoryUser, _ = databroker.GetViaJSON[directory.User](ctx, client, directory.UserRecordType, userID)
|
||||
if dst.DirectoryUser != nil {
|
||||
for _, groupID := range dst.DirectoryUser.GroupIDs {
|
||||
directoryGroup, _ := databroker.GetViaJSON[directory.Group](ctx, client, directory.GroupRecordType, groupID)
|
||||
if directoryGroup != nil {
|
||||
dst.DirectoryGroups = append(dst.DirectoryGroups, directoryGroup)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Authenticate) saveSessionToDataBroker(
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
"github.com/pomerium/datasource/pkg/directory"
|
||||
"github.com/pomerium/pomerium/internal/httputil"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/session"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||
|
@ -20,6 +21,10 @@ type UserInfoData struct {
|
|||
Session *session.Session
|
||||
User *user.User
|
||||
|
||||
IsEnterprise bool
|
||||
DirectoryUser *directory.User
|
||||
DirectoryGroups []*directory.Group
|
||||
|
||||
WebAuthnCreationOptions *webauthn.PublicKeyCredentialCreationOptions
|
||||
WebAuthnRequestOptions *webauthn.PublicKeyCredentialRequestOptions
|
||||
WebAuthnURL string
|
||||
|
@ -38,6 +43,13 @@ func (data UserInfoData) ToJSON() map[string]any {
|
|||
if bs, err := protojson.Marshal(data.User); err == nil {
|
||||
m["user"] = json.RawMessage(bs)
|
||||
}
|
||||
m["isEnterprise"] = data.IsEnterprise
|
||||
if data.DirectoryUser != nil {
|
||||
m["directoryUser"] = data.DirectoryUser
|
||||
}
|
||||
if len(data.DirectoryGroups) > 0 {
|
||||
m["directoryGroups"] = data.DirectoryGroups
|
||||
}
|
||||
m["webAuthnCreationOptions"] = data.WebAuthnCreationOptions
|
||||
m["webAuthnRequestOptions"] = data.WebAuthnRequestOptions
|
||||
m["webAuthnUrl"] = data.WebAuthnURL
|
||||
|
|
1
go.mod
1
go.mod
|
@ -46,6 +46,7 @@ require (
|
|||
github.com/ory/dockertest/v3 v3.9.1
|
||||
github.com/peterbourgon/ff/v3 v3.3.0
|
||||
github.com/pomerium/csrf v1.7.0
|
||||
github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524
|
||||
github.com/pomerium/webauthn v0.0.0-20211014213840-422c7ce1077f
|
||||
github.com/prometheus/client_golang v1.13.1
|
||||
github.com/prometheus/client_model v0.3.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -789,6 +789,8 @@ github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8E
|
|||
github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI=
|
||||
github.com/pomerium/csrf v1.7.0 h1:Qp4t6oyEod3svQtKfJZs589mdUTWKVf7q0PgCKYCshY=
|
||||
github.com/pomerium/csrf v1.7.0/go.mod h1:hAPZV47mEj2T9xFs+ysbum4l7SF1IdrryYaY6PdoIqw=
|
||||
github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524 h1:3YQY1sb54tEEbr0L73rjHkpLB0IB6qh3zl1+XQbMLis=
|
||||
github.com/pomerium/datasource v0.18.2-0.20221108160055-c6134b5ed524/go.mod h1:7fGbUYJnU8RcxZJvUvhukOIBv1G7LWDAHMfDxAf5+Y0=
|
||||
github.com/pomerium/webauthn v0.0.0-20211014213840-422c7ce1077f h1:442shkoI4Oh4RHdzFaGma1t9Ji/T+8pfCxQQzmY5kj8=
|
||||
github.com/pomerium/webauthn v0.0.0-20211014213840-422c7ce1077f/go.mod h1:wgH3ualWdXu/qwbhOoSQedXzco+38Iz7qKKGCJcKPXg=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
|
|
|
@ -3,9 +3,11 @@ package databroker
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
|
@ -43,6 +45,34 @@ func Get(ctx context.Context, client DataBrokerServiceClient, object recordObjec
|
|||
return res.GetRecord().GetData().UnmarshalTo(object)
|
||||
}
|
||||
|
||||
// GetViaJSON gets a record from the databroker, marshals it to JSON, and then unmarshals it to the given type.
|
||||
func GetViaJSON[T any](ctx context.Context, client DataBrokerServiceClient, recordType, recordID string) (*T, error) {
|
||||
res, err := client.Get(ctx, &GetRequest{
|
||||
Type: recordType,
|
||||
Id: recordID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msg, err := res.GetRecord().GetData().UnmarshalNew()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bs, err := protojson.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var obj T
|
||||
err = json.Unmarshal(bs, &obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &obj, nil
|
||||
}
|
||||
|
||||
// Put puts a record into the databroker.
|
||||
func Put(ctx context.Context, client DataBrokerServiceClient, objects ...recordObject) (*PutResponse, error) {
|
||||
records := make([]*Record, len(objects))
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { Group } from "../types";
|
||||
import IDField from "./IDField";
|
||||
import Section from "./Section";
|
||||
import Alert from "@mui/material/Alert";
|
||||
import Table from "@mui/material/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableCell from "@mui/material/TableCell";
|
||||
|
@ -9,12 +7,21 @@ import TableHead from "@mui/material/TableHead";
|
|||
import TableRow from "@mui/material/TableRow";
|
||||
import React, { FC } from "react";
|
||||
|
||||
import { Group } from "../types";
|
||||
import IDField from "./IDField";
|
||||
import Section from "./Section";
|
||||
|
||||
export type GroupDetailsProps = {
|
||||
isEnterprise: boolean;
|
||||
groups: Group[];
|
||||
};
|
||||
export const GroupDetails: FC<GroupDetailsProps> = ({ groups }) => {
|
||||
export const GroupDetails: FC<GroupDetailsProps> = ({
|
||||
isEnterprise,
|
||||
groups,
|
||||
}) => {
|
||||
return (
|
||||
<Section title="Groups">
|
||||
{isEnterprise ? (
|
||||
<TableContainer>
|
||||
<Table size="small">
|
||||
<TableHead>
|
||||
|
@ -35,6 +42,15 @@ export const GroupDetails: FC<GroupDetailsProps> = ({ groups }) => {
|
|||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
) : (
|
||||
<Alert severity="info">
|
||||
Groups via directory sync are available in{" "}
|
||||
<a href="https://www.pomerium.com/enterprise-sales/">
|
||||
Pomerium Enterprise
|
||||
</a>
|
||||
.
|
||||
</Alert>
|
||||
)}
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -84,7 +84,10 @@ const UserInfoPage: FC<UserInfoPageProps> = ({ data }) => {
|
|||
{subpage === "User" && <SessionDetails session={data?.session} />}
|
||||
|
||||
{subpage === "Groups Info" && (
|
||||
<GroupDetails groups={data?.directoryGroups} />
|
||||
<GroupDetails
|
||||
isEnterprise={data?.isEnterprise}
|
||||
groups={data?.directoryGroups}
|
||||
/>
|
||||
)}
|
||||
|
||||
{subpage === "Devices Info" && (
|
||||
|
|
|
@ -103,6 +103,7 @@ export type UserInfoData = {
|
|||
csrfToken: string;
|
||||
directoryGroups?: Group[];
|
||||
directoryUser?: DirectoryUser;
|
||||
isEnterprise?: boolean;
|
||||
session?: Session;
|
||||
user?: User;
|
||||
webAuthnCreationOptions?: WebAuthnCreationOptions;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue