Skip to content

Commit

Permalink
Try this for the new service accounts ... (#2355)
Browse files Browse the repository at this point in the history
* Handle CRC service accounts.

No-Issue

Signed-off-by: James Tanner <[email protected]>
  • Loading branch information
jctanner authored Nov 22, 2024
1 parent 10633ef commit 28850d4
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 12 deletions.
32 changes: 25 additions & 7 deletions galaxy_ng/app/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,32 @@ def authenticate(self, request):
return None

header = self._decode_header(request.META[self.header])
identity = header.get("identity")
if identity is None:
raise AuthenticationFailed

try:
identity = header['identity']
account = identity['account_number']

user = identity['user']
username = user['username']
except KeyError:
identity_type = identity.get("type", "User")
if identity_type == "User":
try:
identity = header['identity']
account = identity['account_number']

user = identity['user']
username = user['username']
except KeyError:
raise AuthenticationFailed
elif identity_type == "ServiceAccount":
try:
service_account = identity['service_account']
# service-account-<uuid4> is too long for the username field
username = service_account['username'].replace('service-account-', '')
# make this the same?
account = username
# all other attributes for service accounts is null
user = {}
except KeyError:
raise AuthenticationFailed
else:
raise AuthenticationFailed

email = user.get('email', '')
Expand Down
2 changes: 1 addition & 1 deletion galaxy_ng/tests/integration/utils/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def wait_for_task_ui_client(gc, task):
if state == 'completed':
break
time.sleep(SLEEP_SECONDS_POLLING)
assert state == 'completed'
assert state == 'completed', ds


def wait_for_namespace_tasks_gk(gc, timeout=300):
Expand Down
114 changes: 110 additions & 4 deletions profiles/insights/proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ type User struct {
IsOrgAdmin bool `json:"is_org_admin"`
}

type ServiceAccount struct {
ClientId string `json:"client_id"`
Username string `json:"username"`
}

type Account struct {
AccountNumber int `json:"account_number"`
User User `json:"user"`
Expand All @@ -60,6 +65,24 @@ type XRHItentity struct {
Entitlements Entitlement `json:"entitlements"`
}

type XRHSVCItentity struct {
Entitlements Entitlement `json:"entitlements"`
Identity struct {
AuthType string `json:"auth_type"`
Internal struct {
AuthTime int `json:"auth_time"`
CrossAccess bool `json:"cross_access"`
OrgID string `json:"org_id"`
} `json:"internal"`
OrgID string `json:"org_id"`
Type string `json:"type"`
ServiceAccount struct {
ClientID string `json:"client_id"`
Username string `json:"username"`
} `json:"service_account"`
} `json:"identity"`
}

var accounts = map[string]Account{
"jdoe": {
AccountNumber: 6089719,
Expand Down Expand Up @@ -103,6 +126,13 @@ var accounts = map[string]Account{
},
}

var serviceAccounts = map[string]ServiceAccount {
"service-account-b69eaf9e-e6a6-4f9e-805e-02987daddfbd": {
Username: "service-account-b69eaf9e-e6a6-4f9e-805e-02987daddfbd",
ClientId: "b69eaf9e-e6a6-4f9e-805e-02987daddfbd",
},
}

func randomString(length int) string {
rand.Seed(time.Now().UnixNano())
b := make([]byte, length)
Expand Down Expand Up @@ -149,19 +179,95 @@ func userToIentityHeader(account Account) string {
return base64.StdEncoding.EncodeToString([]byte(data))
}

func serviceAccountToIentityHeader(svc_account ServiceAccount) string {
/*
{
"entitlements": {},
"identity": {
"auth_type": "jwt-auth",
"internal": {
"auth_time": 500,
"cross_access": false,
"org_id": "456"
},
"org_id": "456",
"type": "ServiceAccount",
"service_account": {
"client_id": "b69eaf9e-e6a6-4f9e-805e-02987daddfbd",
"username": "service-account-b69eaf9e-e6a6-4f9e-805e-02987daddfbd"
}
}
}
*/

data := XRHSVCItentity{
Entitlements: Entitlement{
Insights: map[string]bool{
"is_entitled": true,
"is_trial": false,
},
},
Identity: struct {
AuthType string `json:"auth_type"`
Internal struct {
AuthTime int `json:"auth_time"`
CrossAccess bool `json:"cross_access"`
OrgID string `json:"org_id"`
} `json:"internal"`
OrgID string `json:"org_id"`
Type string `json:"type"`
ServiceAccount struct {
ClientID string `json:"client_id"`
Username string `json:"username"`
} `json:"service_account"`
}{
AuthType: "jwt-auth",
Internal: struct {
AuthTime int `json:"auth_time"`
CrossAccess bool `json:"cross_access"`
OrgID string `json:"org_id"`
}{
AuthTime: 500,
CrossAccess: false,
OrgID: "456",
},
OrgID: "456",
Type: "ServiceAccount",
ServiceAccount: struct {
ClientID string `json:"client_id"`
Username string `json:"username"`
}{
ClientID: svc_account.ClientId,
Username: svc_account.Username,
},
},
}
jsonData, _ := json.MarshalIndent(data, "", " ")

fmt.Printf("Setting X-RH-IDENTITY: %s\n", string(jsonData))
return base64.StdEncoding.EncodeToString([]byte(jsonData))

}

func setRHIdentityHeader(req *http.Request) {
auth_header := req.Header.Get("Authorization")

if auth_header != "" {
if strings.Contains(auth_header, "Basic") {

user, pass, _ := req.BasicAuth()

fmt.Printf("Authenticating with basic auth: %s:%s\n", user, pass)

if account, ok := accounts[user]; ok {
req.Header.Set("X-RH-IDENTITY", userToIentityHeader(account))
} else {
fmt.Printf("User not found: %s", user)
if svc_account, ok := serviceAccounts[user]; ok {
req.Header.Set("X-RH-IDENTITY", serviceAccountToIentityHeader(svc_account))
} else {

if account, ok := accounts[user]; ok {
req.Header.Set("X-RH-IDENTITY", userToIentityHeader(account))
} else {
fmt.Printf("User not found: %s", user)
}
}

} else if strings.Contains(auth_header, "Bearer") {
Expand Down

0 comments on commit 28850d4

Please sign in to comment.