Skip to content

Commit a630982

Browse files
committed
got links working
1 parent 6786ca2 commit a630982

File tree

5 files changed

+102
-18
lines changed

5 files changed

+102
-18
lines changed

coderd/audit.go

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd
22

33
import (
4+
"context"
45
"database/sql"
56
"encoding/json"
67
"fmt"
@@ -14,6 +15,7 @@ import (
1415
"github.com/google/uuid"
1516
"github.com/tabbed/pqtype"
1617

18+
"cdr.dev/slog"
1719
"github.com/coder/coder/coderd/database"
1820
"github.com/coder/coder/coderd/httpapi"
1921
"github.com/coder/coder/coderd/httpmw"
@@ -69,7 +71,7 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
6971
}
7072

7173
httpapi.Write(ctx, rw, http.StatusOK, codersdk.AuditLogResponse{
72-
AuditLogs: convertAuditLogs(dblogs),
74+
AuditLogs: api.convertAuditLogs(ctx, dblogs),
7375
Count: dblogs[0].Count,
7476
})
7577
}
@@ -147,17 +149,17 @@ func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) {
147149
rw.WriteHeader(http.StatusNoContent)
148150
}
149151

150-
func convertAuditLogs(dblogs []database.GetAuditLogsOffsetRow) []codersdk.AuditLog {
152+
func (api *API) convertAuditLogs(ctx context.Context, dblogs []database.GetAuditLogsOffsetRow) []codersdk.AuditLog {
151153
alogs := make([]codersdk.AuditLog, 0, len(dblogs))
152154

153155
for _, dblog := range dblogs {
154-
alogs = append(alogs, convertAuditLog(dblog))
156+
alogs = append(alogs, api.convertAuditLog(ctx, dblog))
155157
}
156158

157159
return alogs
158160
}
159161

160-
func convertAuditLog(dblog database.GetAuditLogsOffsetRow) codersdk.AuditLog {
162+
func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogsOffsetRow) codersdk.AuditLog {
161163
ip, _ := netip.AddrFromSlice(dblog.Ip.IPNet.IP)
162164

163165
diff := codersdk.AuditDiff{}
@@ -199,21 +201,60 @@ func convertAuditLog(dblog database.GetAuditLogsOffsetRow) codersdk.AuditLog {
199201
AdditionalFields: dblog.AdditionalFields,
200202
Description: auditLogDescription(dblog),
201203
User: user,
204+
ResourceLink: api.auditLogResourceLink(ctx, dblog),
205+
}
206+
}
207+
208+
type AdditionalFields struct {
209+
WorkspaceName string
210+
BuildNumber string
211+
}
212+
213+
func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAuditLogsOffsetRow) string {
214+
switch alog.ResourceType {
215+
case database.ResourceTypeOrganization:
216+
return ""
217+
case database.ResourceTypeTemplate:
218+
return ""
219+
case database.ResourceTypeTemplateVersion:
220+
return ""
221+
case database.ResourceTypeUser:
222+
return ""
223+
case database.ResourceTypeWorkspace:
224+
return fmt.Sprintf("/@%s/%s",
225+
alog.UserUsername.String, alog.ResourceTarget)
226+
case database.ResourceTypeWorkspaceBuild:
227+
additionalFieldsBytes := []byte(alog.AdditionalFields)
228+
var additionalFields AdditionalFields
229+
err := json.Unmarshal(additionalFieldsBytes, &additionalFields)
230+
if err != nil {
231+
api.Logger.Error(ctx, "could not unmarshal workspace name for friendly string", slog.Error(err))
232+
}
233+
return fmt.Sprintf("/@%s/%s/builds/%s",
234+
alog.UserUsername.String, additionalFields.WorkspaceName, additionalFields.BuildNumber)
235+
case database.ResourceTypeGitSshKey:
236+
return ""
237+
case database.ResourceTypeApiKey:
238+
return ""
239+
case database.ResourceTypeGroup:
240+
return ""
241+
default:
242+
return ""
202243
}
203244
}
204245

205246
func auditLogDescription(alog database.GetAuditLogsOffsetRow) string {
206-
str := fmt.Sprintf("{user} %s %s",
247+
str := fmt.Sprintf("{user} %s",
207248
codersdk.AuditAction(alog.Action).FriendlyString(),
208-
codersdk.ResourceType(alog.ResourceType).FriendlyString(),
209249
)
210250

211251
// Strings for workspace_builds follow the below format:
212252
// "{user} started workspace build for {target}"
213253
// where target is a workspace instead of the workspace build,
214254
// passed in on the FE via AuditLog.AdditionalFields rather than derived in request.go:35
215-
if alog.ResourceType == database.ResourceTypeWorkspaceBuild {
216-
str += " for"
255+
if alog.ResourceType != database.ResourceTypeWorkspaceBuild {
256+
str += fmt.Sprintf(" %s",
257+
codersdk.ResourceType(alog.ResourceType).FriendlyString())
217258
}
218259

219260
// We don't display the name for git ssh keys. It's fairly long and doesn't

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"net/url"
1111
"reflect"
12+
"strconv"
1213
"sync"
1314
"sync/atomic"
1415
"time"
@@ -541,6 +542,7 @@ func (server *Server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*p
541542
// can form a friendly string for the user.
542543
workspaceResourceInfo := map[string]string{
543544
"workspaceName": workspace.Name,
545+
"buildNumber": strconv.FormatInt(int64(build.BuildNumber), 10),
544546
}
545547

546548
wriBytes, err := json.Marshal(workspaceResourceInfo)
@@ -756,6 +758,7 @@ func (server *Server) CompleteJob(ctx context.Context, completed *proto.Complete
756758
// can form a friendly string for the user.
757759
workspaceResourceInfo := map[string]string{
758760
"workspaceName": workspace.Name,
761+
"buildNumber": strconv.FormatInt(int64(workspaceBuild.BuildNumber), 10),
759762
}
760763

761764
wriBytes, err := json.Marshal(workspaceResourceInfo)

codersdk/audit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ type AuditLog struct {
102102
StatusCode int32 `json:"status_code"`
103103
AdditionalFields json.RawMessage `json:"additional_fields"`
104104
Description string `json:"description"`
105+
ResourceLink string `json:"resource_link"`
105106

106107
User *User `json:"user"`
107108
}

site/src/api/typesGenerated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export interface AuditLog {
6767
readonly status_code: number
6868
readonly additional_fields: Record<string, string>
6969
readonly description: string
70+
readonly resource_link: string
7071
readonly user?: User
7172
}
7273

site/src/components/AuditLogRow/AuditLogRow.tsx

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,45 @@ import { PaletteIndex } from "theme/palettes"
1515
import userAgentParser from "ua-parser-js"
1616
import { combineClasses } from "util/combineClasses"
1717
import { AuditLogDiff } from "./AuditLogDiff"
18+
import { Link } from "react-router-dom"
1819

19-
export const readableActionMessage = (auditLog: AuditLog): string => {
20+
// const determineInitiator = (auditLog: AuditLog): string => {
21+
// return auditLog.
22+
// }
23+
24+
const determineResourceTarget = (auditLog: AuditLog): string => {
2025
let target = auditLog.resource_target.trim()
2126

2227
// audit logs with a resource_type of workspace build use workspace name as a target
23-
if (
24-
auditLog.resource_type === "workspace_build" &&
25-
auditLog.additional_fields.workspaceName
26-
) {
27-
target = auditLog.additional_fields.workspaceName.trim()
28+
if (auditLog.resource_type === "workspace_build") {
29+
// target = auditLog.additional_fields.workspaceName.trim()
30+
target = "build"
2831
}
2932

33+
return target
34+
}
35+
36+
export const readableActionMessage = (auditLog: AuditLog): string => {
37+
// let target = auditLog.resource_target.trim()
38+
39+
// audit logs with a resource_type of workspace build use workspace name as a target
40+
// if (
41+
// auditLog.resource_type === "workspace_build" &&
42+
// auditLog.additional_fields.workspaceName
43+
// ) {
44+
// target = auditLog.additional_fields.workspaceName.trim()
45+
// }
46+
3047
return auditLog.description
31-
.replace("{user}", `<strong>${auditLog.user?.username.trim()}</strong>`)
32-
.replace("{target}", `<strong>${target}</strong>`)
48+
.replace("{user}", `${auditLog.user?.username.trim()}`)
49+
.replace("{target}", "")
50+
51+
// return auditLog.description
52+
// .replace("{user}", `<strong>${auditLog.user?.username.trim()}</strong>`)
53+
// .replace(
54+
// "{target}",
55+
// `<Link to=/@${auditLog.user?.username.trim()}/${target}>${target}</Link>`,
56+
// )
3357
}
3458

3559
const httpStatusColor = (httpStatus: number): PaletteIndex => {
@@ -119,11 +143,25 @@ export const AuditLogRow: React.FC<AuditLogRowProps> = ({
119143
alignItems="baseline"
120144
spacing={1}
121145
>
122-
<span
146+
<span>
147+
{readableActionMessage(auditLog)}{" "}
148+
<Link to={auditLog.resource_link}>
149+
{determineResourceTarget(auditLog)}
150+
</Link>
151+
{auditLog.resource_type === "workspace_build" &&
152+
auditLog.additional_fields.workspaceName && (
153+
<span>
154+
{" "}
155+
for workspace{" "}
156+
{auditLog.additional_fields.workspaceName}
157+
</span>
158+
)}
159+
</span>
160+
{/* <span
123161
dangerouslySetInnerHTML={{
124162
__html: readableActionMessage(auditLog),
125163
}}
126-
/>
164+
/> */}
127165
<span className={styles.auditLogTime}>
128166
{new Date(auditLog.time).toLocaleTimeString()}
129167
</span>

0 commit comments

Comments
 (0)