Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions oauthproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -827,14 +827,14 @@ func (p *OAuthProxy) backendLogout(rw http.ResponseWriter, req *http.Request, si
if resp.StatusCode() != 200 {
logger.Errorf("error while calling backend logout url, returned error code %v", resp.StatusCode())
}
p.picsAuditClient.CreateSuccessfulLogoutAuditEntry(session, req.RequestURI, req.Header.Get("edisp-org-id"))
p.picsAuditClient.CreateSuccessfulLogoutAuditEntry(session, req.RequestURI, req.Header.Get("edisp-org-id"), req)
} else {
if providerData.BackendRevokeAccessTokenURL != "" {
err := PicsRevokeAccessToken(providerData.BackendRevokeAccessTokenURL, session.AccessToken, providerData.ClientID, providerData.ClientSecret)
if err != nil {
logger.Errorf("error while calling backend revoke access token: %v", err)
} else {
p.picsAuditClient.CreateSuccessfulRevokeAccessTokenAuditEntry(session, req.RequestURI, req.Header.Get("edisp-org-id"))
p.picsAuditClient.CreateSuccessfulRevokeAccessTokenAuditEntry(session, req.RequestURI, req.Header.Get("edisp-org-id"), req)
}
}

Expand Down Expand Up @@ -1010,7 +1010,7 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
p.ErrorPage(rw, req, http.StatusInternalServerError, err.Error())
return
}
p.picsAuditClient.CreateSuccessfulLoginAuditEntry(session, appRedirect, req.Header.Get("edisp-org-id"))
p.picsAuditClient.CreateSuccessfulLoginAuditEntry(session, appRedirect, req.Header.Get("edisp-org-id"), req)
http.Redirect(rw, req, appRedirect, http.StatusFound)
} else {
logger.PrintAuthf(session.Email, req, logger.AuthFailure, "Invalid authentication via OAuth2: unauthorized")
Expand Down
51 changes: 41 additions & 10 deletions pkg/pics/audit/audit_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"errors"
"fmt"
"log"
"net"
"net/http"
"os"
"strings"
"time"

Expand Down Expand Up @@ -52,34 +55,60 @@ func NewAuditClient(opts *ClientOpts) (*Client, error) {
return &Client{enabled: opts.Enabled, apiSignature: apiSignature, client: client, opts: opts}, nil
}

func (c *Client) CreateSuccessfulLoginAuditEntry(ss *sessions.SessionState, appURL string, tenantID string) {
func (c *Client) CreateSuccessfulLoginAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, req *http.Request) {
coding := Coding{
System: "http://hl7.org/fhir/ValueSet/audit-event-type", Version: "1", Code: "110114", Display: "User Authentication"}
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding)
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding, req)
}

func (c *Client) CreateFailedLoginAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, errorDesc string) {
func (c *Client) CreateFailedLoginAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, errorDesc string, req *http.Request) {
coding := Coding{
System: "http://hl7.org/fhir/ValueSet/audit-event-type", Version: "1", Code: "110114", Display: "User Authentication"}
c.createAuditEntry(ss, appURL, tenantID, "1", errorDesc, &coding)
c.createAuditEntry(ss, appURL, tenantID, "1", errorDesc, &coding, req)
}

func (c *Client) CreateSuccessfulLogoutAuditEntry(ss *sessions.SessionState, appURL string, tenantID string) {
func (c *Client) CreateSuccessfulLogoutAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, req *http.Request) {
coding := Coding{
System: "http://hl7.org/fhir/ValueSet/audit-event-type", Version: "1", Code: "110123", Display: "User Logout All Sessions"}
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding)
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding, req)
}

func (c *Client) CreateSuccessfulRevokeAccessTokenAuditEntry(ss *sessions.SessionState, appURL string, tenantID string) {
func (c *Client) CreateSuccessfulRevokeAccessTokenAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, req *http.Request) {
coding := Coding{
System: "http://hl7.org/fhir/ValueSet/audit-event-type", Version: "1", Code: "110123", Display: "User revoked access token"}
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding)
c.createAuditEntry(ss, appURL, tenantID, "0", "Success", &coding, req)
}

func (c *Client) createAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, outcomeCode string, outcomeDesc string, coding *Coding) {
func (c *Client) createAuditEntry(ss *sessions.SessionState, appURL string, tenantID string, outcomeCode string, outcomeDesc string, coding *Coding, req *http.Request) {
if !c.enabled {
return
}

// Service/component identifier
serviceIDs := []string{"oauth2proxy"}
var targetIP string
if hn, err := os.Hostname(); err == nil {
serviceIDs = append(serviceIDs, hn)
addrs, err := net.LookupHost(hn)
if err == nil && len(addrs) > 0 {
targetIP = addrs[0]
} else {
targetIP = hn
}
} else {
targetIP = "unknown"
}

// Extract source IP address
sourceIP := ""
if req != nil {
sourceIP = req.RemoteAddr
if xff := req.Header.Get("X-Forwarded-For"); xff != "" {
ips := strings.Split(xff, ",")
sourceIP = strings.TrimSpace(ips[0])
}
}

auditObject := RootEvent{
ResourceType: "AuditEvent",
Event: &Event{
Expand All @@ -88,7 +117,6 @@ func (c *Client) createAuditEntry(ss *sessions.SessionState, appURL string, tena
DateTime: time.Now().UTC().Format(time.RFC3339),
Outcome: outcomeCode,
OutcomeDesc: outcomeDesc},

Participant: []*Participant{
{AltID: ss.User, UserID: UserID{Value: ss.Email}, Name: ss.PreferredUsername, Requestor: true}},
Source: Source{
Expand Down Expand Up @@ -133,6 +161,9 @@ func (c *Client) createAuditEntry(ss *sessions.SessionState, appURL string, tena
},
},
},
ServiceIDs: serviceIDs,
SourceIPAddress: sourceIP,
TargetIPAddress: targetIP,
}

auditMessage, err := json.Marshal(auditObject)
Expand Down
13 changes: 8 additions & 5 deletions pkg/pics/audit/audit_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,12 @@ type Event struct {
}

type RootEvent struct {
ResourceType string `json:"resourceType,omitempty"`
Event *Event `json:"event,omitempty"`
Participant []*Participant `json:"participant,omitempty"`
Source Source `json:"source,omitempty"`
Object []*Object `json:"object,omitempty"`
ResourceType string `json:"resourceType,omitempty"`
Event *Event `json:"event,omitempty"`
Participant []*Participant `json:"participant,omitempty"`
Source Source `json:"source,omitempty"`
Object []*Object `json:"object,omitempty"`
ServiceIDs []string `json:"service_ids,omitempty"`
SourceIPAddress string `json:"source_ip_address,omitempty"`
TargetIPAddress string `json:"target_ip_address,omitempty"`
}