mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-04 23:45:07 +00:00
merge main into next
This commit is contained in:
parent
b5564572bc
commit
bd23a7a56f
1
.github/workflows/console.yml
vendored
1
.github/workflows/console.yml
vendored
@ -30,6 +30,7 @@ jobs:
|
|||||||
-
|
-
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v3
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
|
continue-on-error: true
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
key: console-${{ hashFiles('console', 'proto', '!console/dist') }}
|
key: console-${{ hashFiles('console', 'proto', '!console/dist') }}
|
||||||
|
1
.github/workflows/core-integration-test.yml
vendored
1
.github/workflows/core-integration-test.yml
vendored
@ -56,6 +56,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v3
|
||||||
id: cache
|
id: cache
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
|
continue-on-error: true
|
||||||
name: restore previous results
|
name: restore previous results
|
||||||
with:
|
with:
|
||||||
key: integration-test-postgres-${{ inputs.core_cache_key }}
|
key: integration-test-postgres-${{ inputs.core_cache_key }}
|
||||||
|
1
.github/workflows/core-unit-test.yml
vendored
1
.github/workflows/core-unit-test.yml
vendored
@ -40,6 +40,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v3
|
||||||
id: cache
|
id: cache
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
|
continue-on-error: true
|
||||||
name: restore previous results
|
name: restore previous results
|
||||||
with:
|
with:
|
||||||
key: unit-test-${{ inputs.core_cache_key }}
|
key: unit-test-${{ inputs.core_cache_key }}
|
||||||
|
1
.github/workflows/core.yml
vendored
1
.github/workflows/core.yml
vendored
@ -41,6 +41,7 @@ jobs:
|
|||||||
-
|
-
|
||||||
uses: actions/cache/restore@v3
|
uses: actions/cache/restore@v3
|
||||||
timeout-minutes: 1
|
timeout-minutes: 1
|
||||||
|
continue-on-error: true
|
||||||
id: cache
|
id: cache
|
||||||
with:
|
with:
|
||||||
key: core-${{ hashFiles( 'go.*', 'openapi', 'cmd', 'pkg/grpc/**/*.go', 'proto', 'internal') }}
|
key: core-${{ hashFiles( 'go.*', 'openapi', 'cmd', 'pkg/grpc/**/*.go', 'proto', 'internal') }}
|
||||||
|
2
Makefile
2
Makefile
@ -83,7 +83,7 @@ console_build: console_dependencies console_client
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) .artifacts/grpc
|
$(RM) -r .artifacts/grpc
|
||||||
$(RM) $(gen_authopt_path)
|
$(RM) $(gen_authopt_path)
|
||||||
$(RM) $(gen_zitadel_path)
|
$(RM) $(gen_zitadel_path)
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ COPY --from=core-assets /go/src/github.com/zitadel/zitadel/internal ./internal
|
|||||||
# #######################################
|
# #######################################
|
||||||
# download console dependencies
|
# download console dependencies
|
||||||
# #######################################
|
# #######################################
|
||||||
FROM node:18-buster AS console-deps
|
FROM node:20-buster AS console-deps
|
||||||
|
|
||||||
WORKDIR /zitadel/console
|
WORKDIR /zitadel/console
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ RUN yarn install --frozen-lockfile
|
|||||||
# #######################################
|
# #######################################
|
||||||
# generate console client
|
# generate console client
|
||||||
# #######################################
|
# #######################################
|
||||||
FROM node:18-buster AS console-client
|
FROM node:20-buster AS console-client
|
||||||
|
|
||||||
WORKDIR /zitadel/console
|
WORKDIR /zitadel/console
|
||||||
|
|
||||||
|
@ -767,7 +767,7 @@ DefaultInstance:
|
|||||||
PreHeader: Verify email
|
PreHeader: Verify email
|
||||||
Subject: Verify email
|
Subject: Verify email
|
||||||
Greeting: Hello {{.DisplayName}},
|
Greeting: Hello {{.DisplayName}},
|
||||||
Text: A new email has been added. Please use the button below to verify your mail. (Code {{.Code}}) If you din't add a new email, please ignore this email.
|
Text: A new email has been added. Please use the button below to verify your email. (Code {{.Code}}) If you din't add a new email, please ignore this email.
|
||||||
ButtonText: Verify email
|
ButtonText: Verify email
|
||||||
- MessageTextType: VerifyPhone
|
- MessageTextType: VerifyPhone
|
||||||
Language: en
|
Language: en
|
||||||
|
@ -35,8 +35,8 @@ FirstInstance:
|
|||||||
# If FirstInstance.Org.Machine.Machine is defined, a service user is created with the IAM_OWNER role, not a human user.
|
# If FirstInstance.Org.Machine.Machine is defined, a service user is created with the IAM_OWNER role, not a human user.
|
||||||
Machine:
|
Machine:
|
||||||
Machine:
|
Machine:
|
||||||
Username: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_USERNAME
|
Username: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME
|
||||||
Name: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_NAME
|
Name: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME
|
||||||
MachineKey:
|
MachineKey:
|
||||||
# date format: 2023-01-01T00:00:00Z
|
# date format: 2023-01-01T00:00:00Z
|
||||||
ExpirationDate: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_EXPIRATIONDATE
|
ExpirationDate: # ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_EXPIRATIONDATE
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"github.com/zitadel/saml/pkg/provider"
|
"github.com/zitadel/saml/pkg/provider"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/http2/h2c"
|
"golang.org/x/net/http2/h2c"
|
||||||
|
@ -157,7 +157,7 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
|
|||||||
this.service
|
this.service
|
||||||
.removeMyAuthFactorOTPEmail()
|
.removeMyAuthFactorOTPEmail()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('USER.TOAST.U2FREMOVED', true);
|
this.toast.showInfo('USER.TOAST.OTPREMOVED', true);
|
||||||
|
|
||||||
this.cleanupList();
|
this.cleanupList();
|
||||||
this.getMFAs();
|
this.getMFAs();
|
||||||
@ -169,7 +169,7 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
|
|||||||
this.service
|
this.service
|
||||||
.removeMyAuthFactorOTPSMS()
|
.removeMyAuthFactorOTPSMS()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('USER.TOAST.U2FREMOVED', true);
|
this.toast.showInfo('USER.TOAST.OTPREMOVED', true);
|
||||||
|
|
||||||
this.cleanupList();
|
this.cleanupList();
|
||||||
this.getMFAs();
|
this.getMFAs();
|
||||||
|
@ -102,6 +102,36 @@ export class UserMfaComponent implements OnInit, OnDestroy {
|
|||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
});
|
});
|
||||||
|
} else if (factor.otpEmail) {
|
||||||
|
this.mgmtUserService
|
||||||
|
.removeHumanAuthFactorOTPEmail(this.user.id)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.OTPREMOVED', true);
|
||||||
|
|
||||||
|
const index = this.dataSource.data.findIndex((mfa) => !!mfa.otpEmail);
|
||||||
|
if (index > -1) {
|
||||||
|
this.dataSource.data.splice(index, 1);
|
||||||
|
}
|
||||||
|
this.getMFAs();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
|
} else if (factor.otpSms) {
|
||||||
|
this.mgmtUserService
|
||||||
|
.removeHumanAuthFactorOTPSMS(this.user.id)
|
||||||
|
.then(() => {
|
||||||
|
this.toast.showInfo('USER.TOAST.OTPREMOVED', true);
|
||||||
|
|
||||||
|
const index = this.dataSource.data.findIndex((mfa) => !!mfa.otpSms);
|
||||||
|
if (index > -1) {
|
||||||
|
this.dataSource.data.splice(index, 1);
|
||||||
|
}
|
||||||
|
this.getMFAs();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
this.toast.showError(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -322,8 +322,12 @@ import {
|
|||||||
RemoveCustomLabelPolicyLogoDarkResponse,
|
RemoveCustomLabelPolicyLogoDarkResponse,
|
||||||
RemoveCustomLabelPolicyLogoRequest,
|
RemoveCustomLabelPolicyLogoRequest,
|
||||||
RemoveCustomLabelPolicyLogoResponse,
|
RemoveCustomLabelPolicyLogoResponse,
|
||||||
|
RemoveHumanAuthFactorOTPEmailRequest,
|
||||||
|
RemoveHumanAuthFactorOTPEmailResponse,
|
||||||
RemoveHumanAuthFactorOTPRequest,
|
RemoveHumanAuthFactorOTPRequest,
|
||||||
RemoveHumanAuthFactorOTPResponse,
|
RemoveHumanAuthFactorOTPResponse,
|
||||||
|
RemoveHumanAuthFactorOTPSMSRequest,
|
||||||
|
RemoveHumanAuthFactorOTPSMSResponse,
|
||||||
RemoveHumanAuthFactorU2FRequest,
|
RemoveHumanAuthFactorU2FRequest,
|
||||||
RemoveHumanAuthFactorU2FResponse,
|
RemoveHumanAuthFactorU2FResponse,
|
||||||
RemoveHumanLinkedIDPRequest,
|
RemoveHumanLinkedIDPRequest,
|
||||||
@ -1805,6 +1809,18 @@ export class ManagementService {
|
|||||||
return this.grpcService.mgmt.removeHumanAuthFactorU2F(req, null).then((resp) => resp.toObject());
|
return this.grpcService.mgmt.removeHumanAuthFactorU2F(req, null).then((resp) => resp.toObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public removeHumanAuthFactorOTPSMS(userId: string): Promise<RemoveHumanAuthFactorOTPSMSResponse.AsObject> {
|
||||||
|
const req = new RemoveHumanAuthFactorOTPSMSRequest();
|
||||||
|
req.setUserId(userId);
|
||||||
|
return this.grpcService.mgmt.removeHumanAuthFactorOTPSMS(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeHumanAuthFactorOTPEmail(userId: string): Promise<RemoveHumanAuthFactorOTPEmailResponse.AsObject> {
|
||||||
|
const req = new RemoveHumanAuthFactorOTPEmailRequest();
|
||||||
|
req.setUserId(userId);
|
||||||
|
return this.grpcService.mgmt.removeHumanAuthFactorOTPEmail(req, null).then((resp) => resp.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
public updateHumanProfile(
|
public updateHumanProfile(
|
||||||
userId: string,
|
userId: string,
|
||||||
firstName?: string,
|
firstName?: string,
|
||||||
|
@ -51,3 +51,58 @@ The object has the following fields and methods:
|
|||||||
Returns the body as JSON object, or throws an error if the body is not a json object.
|
Returns the body as JSON object, or throws an error if the body is not a json object.
|
||||||
- `text()` *string*
|
- `text()` *string*
|
||||||
Returns the body
|
Returns the body
|
||||||
|
|
||||||
|
## UUID
|
||||||
|
|
||||||
|
This module provides functionality to generate a UUID
|
||||||
|
|
||||||
|
### Import
|
||||||
|
|
||||||
|
```js
|
||||||
|
let uuid = require("zitadel/uuid")
|
||||||
|
```
|
||||||
|
|
||||||
|
### `uuid.vX()` function
|
||||||
|
|
||||||
|
This function generates a UUID using [google/uuid](https://github.com/google/uuid). `vX` allows to define the UUID version:
|
||||||
|
|
||||||
|
- `uuid.v1()` *string*
|
||||||
|
Generates a UUID version 1, based on date-time and MAC address
|
||||||
|
- `uuid.v3(namespace, data)` *string*
|
||||||
|
Generates a UUID version 3, based on the provided namespace using MD5
|
||||||
|
- `uuid.v4()` *string*
|
||||||
|
Generates a UUID version 4, which is randomly generated
|
||||||
|
- `uuid.v5(namespace, data)` *string*
|
||||||
|
Generates a UUID version 5, based on the provided namespace using SHA1
|
||||||
|
|
||||||
|
#### Parameters
|
||||||
|
|
||||||
|
- `namespace` *UUID*/*string*
|
||||||
|
Namespace to be used in the hashing function. Either provide one of defined [namespaces](#namespaces) or a string representing a UUID.
|
||||||
|
- `data` *[]byte*/*string*
|
||||||
|
data to be used in the hashing function. Possible types are []byte or string.
|
||||||
|
|
||||||
|
### Namespaces
|
||||||
|
|
||||||
|
The following predefined namespaces can be used for `uuid.v3` and `uuid.v5`:
|
||||||
|
|
||||||
|
- `uuid.namespaceDNS` *UUID*
|
||||||
|
6ba7b810-9dad-11d1-80b4-00c04fd430c8
|
||||||
|
- `uuid.namespaceURL` *UUID*
|
||||||
|
6ba7b811-9dad-11d1-80b4-00c04fd430c8
|
||||||
|
- `uuid.namespaceOID` *UUID*
|
||||||
|
6ba7b812-9dad-11d1-80b4-00c04fd430c8
|
||||||
|
- `uuid.namespaceX500` *UUID*
|
||||||
|
6ba7b814-9dad-11d1-80b4-00c04fd430c8
|
||||||
|
|
||||||
|
### Example
|
||||||
|
```js
|
||||||
|
let uuid = require("zitadel/uuid")
|
||||||
|
function setUUID(ctx, api) {
|
||||||
|
if (api.metadata === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
api.v1.user.appendMetadata('custom-id', uuid.v4());
|
||||||
|
}
|
||||||
|
```
|
87
docs/docs/legal/onboarding-support.md
Normal file
87
docs/docs/legal/onboarding-support.md
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
---
|
||||||
|
title: Description of onboarding support services for ZITADEL
|
||||||
|
sidebar_label: Onboarding support
|
||||||
|
custom_edit_url: null
|
||||||
|
---
|
||||||
|
|
||||||
|
This annex of the [Framework Agreement](terms-of-service) describes the onboarding support services offered by us for our services.
|
||||||
|
|
||||||
|
Last revised: October 12, 2023
|
||||||
|
|
||||||
|
Our onboarding support should help you, as a new customer, to get a better understanding on how to integrate ZITADEL into your solution, how to tackle the migration, and ensure a highly-available day-to-day operation.
|
||||||
|
|
||||||
|
Onboarding support services can be offered to customers that enter a ZITADEL Cloud or a ZITADEL Enterprise subscription.
|
||||||
|
|
||||||
|
If you intend to use the open source version exclusively then please join our community chat or Github.
|
||||||
|
Your questions might help other people in the community and will make our project better over time.
|
||||||
|
|
||||||
|
Please [contact us](https://zitadel.com/contact) for a quote and to get started with onboarding support.
|
||||||
|
Below you will find topics covered and scope of the offered services.
|
||||||
|
|
||||||
|
## Proof of value
|
||||||
|
|
||||||
|
Within a short time-frame, f.e. 3 weeks, we can show the value of using our services and have the ability to establish the proof a of working setup for your most critical use cases.
|
||||||
|
We may offer to support you during an initial period to evaluate next steps.
|
||||||
|
Before the start of the period we may ask you to provide a description of your critical use cases and a high-level overview of your planned integration architecture.
|
||||||
|
During this period you should make sure that you have the necessary resources on your side to complete the proof of value.
|
||||||
|
|
||||||
|
## Onboarding term
|
||||||
|
|
||||||
|
With the onboarding support we provide the initial knowledge transfer to configure and operate ZITADEL.
|
||||||
|
During the term you will get direct access to our engineering team via [Technical Account Management](./support-services.md#technical-account-manager).
|
||||||
|
Duration is typically 3 months but this could vary depending on your requirements.
|
||||||
|
|
||||||
|
We offer an onboarding term in combination with ZITADEL Enterprise subscriptions.
|
||||||
|
|
||||||
|
### Topics covered
|
||||||
|
|
||||||
|
Topics of the onboarding term may include:
|
||||||
|
|
||||||
|
- Administration
|
||||||
|
- DevOps (Operation)
|
||||||
|
- Architecture
|
||||||
|
- Integration
|
||||||
|
- Migration
|
||||||
|
- Security Best Practices & Go-Live Checkup
|
||||||
|
|
||||||
|
The scope will be tailored to your requirements.
|
||||||
|
|
||||||
|
More details
|
||||||
|
|
||||||
|
- IAM Configuration
|
||||||
|
- Walk-though all features
|
||||||
|
- Users / Manuals
|
||||||
|
- Authentication & Management APIs
|
||||||
|
- Validation of tokens
|
||||||
|
- Client integration best-practices
|
||||||
|
- Event types
|
||||||
|
- Database schemas and compute models
|
||||||
|
- Accessing database
|
||||||
|
- Observability (Logs, Errors, Metrics, Tracing)
|
||||||
|
- Operations best practices (Deployment, Backup, Networking etc.)
|
||||||
|
- Check prerequisites and architecture
|
||||||
|
- Troubleshoot installation and configuration of ZITADEL
|
||||||
|
- Troubleshoot and configuration connectivity to the database
|
||||||
|
- Functional testing of the ZITADEL instance
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Out of scope</summary>
|
||||||
|
<ul>
|
||||||
|
<li>Performance testing</li>
|
||||||
|
<li>Setting up or maintaining backup storage</li>
|
||||||
|
<li>Running multiple ZITADEL instances on the same cluster</li>
|
||||||
|
<li>Integration into internal monitoring and alerting</li>
|
||||||
|
<li>Multi-cluster architecture deployments</li>
|
||||||
|
<li>DNS, Network and Firewall configuration</li>
|
||||||
|
<li>Customer-specific Kubernetes configuration needs</li>
|
||||||
|
<li>Non-production environments</li>
|
||||||
|
<li>Production deployment</li>
|
||||||
|
<li>Application-side coding, configuration, or tuning</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Continuous support
|
||||||
|
|
||||||
|
After the onboarding phase has ended we will provide continuous support according to your subscription.
|
||||||
|
We can provide you with continued access to the technical account management in our Enterprise subscriptions.
|
@ -10,7 +10,7 @@ This annex of the [Framework Agreement](terms-of-service) and the [Support Servi
|
|||||||
Support Services for products and services provided by ZITADEL is offered to customers according to the terms and conditions outlined in this document.
|
Support Services for products and services provided by ZITADEL is offered to customers according to the terms and conditions outlined in this document.
|
||||||
The customer may purchase support services from ZITADEL (CAOS Ltd.) directly.
|
The customer may purchase support services from ZITADEL (CAOS Ltd.) directly.
|
||||||
|
|
||||||
Last revised: March 15, 2023
|
Last revised: October 6, 2023
|
||||||
|
|
||||||
## Support Services
|
## Support Services
|
||||||
|
|
||||||
@ -82,7 +82,8 @@ Phone Support | +41 43 215 27 34
|
|||||||
ZITADEL will enhance its support offering by providing eligible clients with a Technical Account Manager (TAM), who will perform the following tasks for up to the specified amount of time per week during the term of service:
|
ZITADEL will enhance its support offering by providing eligible clients with a Technical Account Manager (TAM), who will perform the following tasks for up to the specified amount of time per week during the term of service:
|
||||||
|
|
||||||
- Provide support and advice regarding best practices on platform, product and configuration covered by the applicable Support Services;
|
- Provide support and advice regarding best practices on platform, product and configuration covered by the applicable Support Services;
|
||||||
- Participate in review calls every other week at mutually agreed times addressing customer’s operational issues.
|
- Participate in review calls every other week at mutually agreed times addressing customer’s operational challenges or complex support requests;
|
||||||
|
- Walk-through of new features and customer feedback.
|
||||||
|
|
||||||
We offer TAM services only bundled with specific subscription plans, and the option to add more TAM hours to these plans.
|
We offer TAM services only bundled with specific subscription plans, and the option to add more TAM hours to these plans.
|
||||||
If you require consulting for your projects, please request a quote via our [website](https://zitadel.com/contact).
|
If you require consulting for your projects, please request a quote via our [website](https://zitadel.com/contact).
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
title: Application Support Trainings
|
|
||||||
---
|
|
||||||
|
|
||||||
## ZITADEL DevOps
|
|
||||||
|
|
||||||
In this session your second level support and operations team will gain an understanding on how to extract relevant information for technical support questions and root cause analysis. We will also present our DevOps best practices and answer your questions.
|
|
||||||
|
|
||||||
**Audience**: 2nd Level Support Staff, Operations
|
|
||||||
**Duration**: 0.5 day
|
|
||||||
|
|
||||||
**Topics covered**:
|
|
||||||
|
|
||||||
- Event types
|
|
||||||
- Database schemas and compute models
|
|
||||||
- Accessing database
|
|
||||||
- Observability (Logs, Errors, Metrics, Tracing)
|
|
||||||
- Operations best practices (Deployment, Backup, Networking etc.)
|
|
||||||
- Q&A
|
|
||||||
|
|
||||||
## ZITADEL Administrator
|
|
||||||
|
|
||||||
In this hands-on training your employees will get a complete overview of the system and learn how to configure and use ZITADEL. Your support staff will gain the required knowledge to provide user-support, while your solution owners gain an understanding about integration of clients.
|
|
||||||
|
|
||||||
**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional)
|
|
||||||
**Duration**: 0.5 days
|
|
||||||
|
|
||||||
**Topics covered**:
|
|
||||||
|
|
||||||
- IAM Configuration
|
|
||||||
- Walk-though all features
|
|
||||||
- Users / Manuals
|
|
||||||
- APIs
|
|
||||||
- Validation of tokens
|
|
||||||
- Client integration best-practices
|
|
||||||
- Q&A
|
|
@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
title: ZITADEL Trainings
|
|
||||||
sidebar_label: Introduction
|
|
||||||
---
|
|
||||||
|
|
||||||
The following pages describe the the trainings provided by ZITADEL. These trainings are intended for onboarding and during the course of a Support Program.
|
|
||||||
|
|
||||||
Training should be held as block-sessions with the relevant staff from your organization.
|
|
||||||
|
|
||||||
## Onboarding Project
|
|
||||||
|
|
||||||
You receive professional onboarding support from our engineers, who help you to setup and configure ZITADEL on your infrastructure.
|
|
||||||
|
|
||||||
[More information](project)
|
|
||||||
|
|
||||||
## Application Support Trainings
|
|
||||||
|
|
||||||
With the application support trainings we provide the initial knowledge transfer to manage and support ZITADEL. The trainings are held as block-sessions with relevant staff from your organization. Prices are flat-fee, excl. expenses.
|
|
||||||
|
|
||||||
* [ZITADEL DevOps](application#zitadel-devops)
|
|
||||||
* [ZITADEL Administrator](application#zitadel-administrator)
|
|
||||||
|
|
||||||
## Recurring Trainings
|
|
||||||
|
|
||||||
While you can benefit from a technical account manager during your term, these trainings are designed to onboard new staff or update staff about larger changes to the platform. Prices are flat-fee, excl. expenses.
|
|
||||||
|
|
||||||
* [ZITADEL Support Refresher](recurring#zitadel-support-refresher)
|
|
||||||
* [ZITADEL Support Onboarding](recurring#zitadel-support-onboarding)
|
|
||||||
|
|
||||||
In case you have any questions please [get in touch](https://zitadel.com/contact).
|
|
@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
title: Onboarding Project
|
|
||||||
---
|
|
||||||
|
|
||||||
Effort required during depends on the complexity of your infrastructure and the overall setup. With a Multi-Zone Setup (excl. Multi-Region), support during this phase requires around 10-25h over 2 weeks. Actual effort is based on time and material.
|
|
||||||
|
|
||||||
Scope of the project is agreed on individual basis.
|
|
||||||
|
|
||||||
## In Scope
|
|
||||||
|
|
||||||
- Check prerequisites and architecture
|
|
||||||
- Troubleshoot installation and configuration of ZITADEL
|
|
||||||
- Troubleshoot and configuration connectivity to the database
|
|
||||||
- Functional testing of the ZITADEL instance
|
|
||||||
|
|
||||||
## Out of Scope
|
|
||||||
|
|
||||||
- Running multiple ZITADEL instances on the same cluster
|
|
||||||
- Integration into internal monitoring and alerting
|
|
||||||
- Multi-cluster architecture deployments
|
|
||||||
- DNS, Network and Firewall configuration
|
|
||||||
- Customer-specific Kubernetes configuration needs
|
|
||||||
- Changes for specific environments
|
|
||||||
- Performance testing
|
|
||||||
- Production deployment
|
|
||||||
- Application-side coding, configuration, or tuning
|
|
||||||
- Changes or configuration on assets used in ZITADEL
|
|
||||||
- Setting up or maintaining backup storage
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- Running Kubernetes with possibility to deploy to namespaces
|
|
||||||
- Inbound and outbound HTTP/2 traffic possible
|
|
||||||
- For being able to send SMS, we need a Twilio sender name, SID and an auth token
|
|
||||||
- ZITADEL also needs to connect to an email relay of your choice. We need the SMTP host, user and app key as well as the ZITADEL emails sender address and name.
|
|
@ -1,33 +0,0 @@
|
|||||||
---
|
|
||||||
title: Recurring Trainings
|
|
||||||
---
|
|
||||||
|
|
||||||
## ZITADEL Support Refresher
|
|
||||||
|
|
||||||
In this session you can refresh knowledge about existing and gain experience with new features of ZITADEL to keep the quality of your support high. We recommend an half day training per support staff.
|
|
||||||
|
|
||||||
**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional)
|
|
||||||
**Duration**: 0.5 day / support staff
|
|
||||||
|
|
||||||
**Topics covered**:
|
|
||||||
|
|
||||||
* Walk-through new features
|
|
||||||
* Review of difficult support issues
|
|
||||||
* Review of customer feedback
|
|
||||||
* Q&A
|
|
||||||
|
|
||||||
## ZITADEL Support Onboarding
|
|
||||||
|
|
||||||
In this hands-on training new support staff will get an overview of the system and learn how to configure and use ZITADEL to provide support for users.
|
|
||||||
|
|
||||||
**Audience**: 1st / 2nd Level Support Staff, Solution Owner, QA Manager (optional)
|
|
||||||
**Duration**: 0.5 days / support staff
|
|
||||||
|
|
||||||
**Topics covered**:
|
|
||||||
|
|
||||||
* Event types
|
|
||||||
* Accessing database
|
|
||||||
* Logs and Errors
|
|
||||||
* Validation of tokens
|
|
||||||
* Walk-through key features
|
|
||||||
* Q&A
|
|
@ -425,6 +425,11 @@ module.exports = {
|
|||||||
items: [
|
items: [
|
||||||
"support/software-release-cycles-support",
|
"support/software-release-cycles-support",
|
||||||
"support/troubleshooting",
|
"support/troubleshooting",
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
label: 'Support Service Descriptions',
|
||||||
|
href: '/legal/support-services',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
label: "Technical Advisory",
|
label: "Technical Advisory",
|
||||||
@ -440,17 +445,6 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
label: "Trainings",
|
|
||||||
collapsed: true,
|
|
||||||
items: [
|
|
||||||
"support/trainings/introduction",
|
|
||||||
"support/trainings/application",
|
|
||||||
"support/trainings/recurring",
|
|
||||||
"support/trainings/project",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -697,6 +691,7 @@ module.exports = {
|
|||||||
"legal/cloud-service-description",
|
"legal/cloud-service-description",
|
||||||
"legal/service-level-description",
|
"legal/service-level-description",
|
||||||
"legal/support-services",
|
"legal/support-services",
|
||||||
|
"legal/onboarding-support",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
30
go.mod
30
go.mod
@ -22,6 +22,7 @@ require (
|
|||||||
github.com/drone/envsubst v1.0.3
|
github.com/drone/envsubst v1.0.3
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.2
|
github.com/envoyproxy/protoc-gen-validate v1.0.2
|
||||||
github.com/fatih/color v1.15.0
|
github.com/fatih/color v1.15.0
|
||||||
|
github.com/go-jose/go-jose/v3 v3.0.0
|
||||||
github.com/go-ldap/ldap/v3 v3.4.5
|
github.com/go-ldap/ldap/v3 v3.4.5
|
||||||
github.com/go-webauthn/webauthn v0.8.6
|
github.com/go-webauthn/webauthn v0.8.6
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
@ -48,11 +49,12 @@ require (
|
|||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/muesli/gamut v0.3.1
|
github.com/muesli/gamut v0.3.1
|
||||||
github.com/muhlemmer/gu v0.3.1
|
github.com/muhlemmer/gu v0.3.1
|
||||||
|
github.com/muhlemmer/httpforwarded v0.1.0
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.2.1
|
github.com/nicksnyder/go-i18n/v2 v2.2.1
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/otp v1.4.0
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/rakyll/statik v0.1.7
|
github.com/rakyll/statik v0.1.7
|
||||||
github.com/rs/cors v1.10.0
|
github.com/rs/cors v1.10.1
|
||||||
github.com/sony/sonyflake v1.2.0
|
github.com/sony/sonyflake v1.2.0
|
||||||
github.com/spf13/cobra v1.7.0
|
github.com/spf13/cobra v1.7.0
|
||||||
github.com/spf13/viper v1.16.0
|
github.com/spf13/viper v1.16.0
|
||||||
@ -60,36 +62,35 @@ require (
|
|||||||
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
|
||||||
github.com/ttacon/libphonenumber v1.2.1
|
github.com/ttacon/libphonenumber v1.2.1
|
||||||
github.com/zitadel/logging v0.4.0
|
github.com/zitadel/logging v0.4.0
|
||||||
github.com/zitadel/oidc/v2 v2.11.0
|
github.com/zitadel/oidc/v3 v3.0.2
|
||||||
github.com/zitadel/passwap v0.4.0
|
github.com/zitadel/passwap v0.4.0
|
||||||
github.com/zitadel/saml v0.1.2
|
github.com/zitadel/saml v0.1.2
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0
|
||||||
go.opentelemetry.io/otel v1.17.0
|
go.opentelemetry.io/otel v1.19.0
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.40.0
|
go.opentelemetry.io/otel/exporters/prometheus v0.40.0
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0
|
||||||
go.opentelemetry.io/otel/metric v1.17.0
|
go.opentelemetry.io/otel/metric v1.19.0
|
||||||
go.opentelemetry.io/otel/sdk v1.17.0
|
go.opentelemetry.io/otel/sdk v1.17.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.40.0
|
go.opentelemetry.io/otel/sdk/metric v0.40.0
|
||||||
go.opentelemetry.io/otel/trace v1.17.0
|
go.opentelemetry.io/otel/trace v1.19.0
|
||||||
golang.org/x/crypto v0.13.0
|
golang.org/x/crypto v0.14.0
|
||||||
golang.org/x/net v0.15.0
|
golang.org/x/net v0.17.0
|
||||||
golang.org/x/oauth2 v0.12.0
|
golang.org/x/oauth2 v0.13.0
|
||||||
golang.org/x/sync v0.3.0
|
golang.org/x/sync v0.3.0
|
||||||
golang.org/x/text v0.13.0
|
golang.org/x/text v0.13.0
|
||||||
google.golang.org/api v0.138.0
|
google.golang.org/api v0.138.0
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d
|
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d
|
||||||
google.golang.org/grpc v1.57.0
|
google.golang.org/grpc v1.57.0
|
||||||
google.golang.org/protobuf v1.31.0
|
google.golang.org/protobuf v1.31.0
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
|
||||||
sigs.k8s.io/yaml v1.3.0
|
sigs.k8s.io/yaml v1.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.43.1 // indirect
|
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.43.1 // indirect
|
||||||
github.com/crewjam/httperr v0.2.0 // indirect
|
github.com/crewjam/httperr v0.2.0 // indirect
|
||||||
github.com/dmarkham/enumer v1.5.8 // indirect
|
github.com/go-chi/chi/v5 v5.0.10 // indirect
|
||||||
github.com/go-logr/logr v1.2.4 // indirect
|
github.com/go-logr/logr v1.2.4 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||||
@ -105,14 +106,11 @@ require (
|
|||||||
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
|
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||||
github.com/muhlemmer/httpforwarded v0.1.0 // indirect
|
|
||||||
github.com/pascaldekloe/name v1.0.0 // indirect
|
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||||
github.com/smartystreets/assertions v1.0.0 // indirect
|
github.com/smartystreets/assertions v1.0.0 // indirect
|
||||||
github.com/zenazn/goji v1.0.1 // indirect
|
github.com/zenazn/goji v1.0.1 // indirect
|
||||||
|
github.com/zitadel/schema v1.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect
|
||||||
golang.org/x/mod v0.12.0 // indirect
|
|
||||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
|
|
||||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
|
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||||
)
|
)
|
||||||
@ -154,7 +152,7 @@ require (
|
|||||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/uuid v1.3.1 // indirect
|
github.com/google/uuid v1.3.1
|
||||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||||
github.com/gorilla/handlers v1.5.1 // indirect
|
github.com/gorilla/handlers v1.5.1 // indirect
|
||||||
@ -203,7 +201,7 @@ require (
|
|||||||
go.opencensus.io v0.24.0 // indirect
|
go.opencensus.io v0.24.0 // indirect
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 // indirect
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 // indirect
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||||
golang.org/x/sys v0.12.0
|
golang.org/x/sys v0.13.0
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
|
53
go.sum
53
go.sum
@ -184,8 +184,6 @@ github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwu
|
|||||||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
|
||||||
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||||
github.com/dmarkham/enumer v1.5.8 h1:fIF11F9l5jyD++YYvxcSH5WgHfeaSGPaN/T4kOQ4qEM=
|
|
||||||
github.com/dmarkham/enumer v1.5.8/go.mod h1:d10o8R3t/gROm2p3BXqTkMt2+HMuxEmWCXzorAruYak=
|
|
||||||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||||
github.com/dop251/goja v0.0.0-20230531210528-d7324b2d74f7/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
github.com/dop251/goja v0.0.0-20230531210528-d7324b2d74f7/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
||||||
github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e h1:UvQD6hTSfeM6hhTQ24Dlw2RppP05W7SWbWb6kubJAog=
|
github.com/dop251/goja v0.0.0-20230828202809-3dbe69dd2b8e h1:UvQD6hTSfeM6hhTQ24Dlw2RppP05W7SWbWb6kubJAog=
|
||||||
@ -267,6 +265,8 @@ github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
|
|||||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
|
||||||
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
|
||||||
|
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||||
@ -275,6 +275,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop
|
|||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
|
||||||
|
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
@ -720,8 +722,6 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
|||||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pascaldekloe/name v1.0.0 h1:n7LKFgHixETzxpRv2R77YgPUFo85QHGZKrdaYm7eY5U=
|
|
||||||
github.com/pascaldekloe/name v1.0.0/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM=
|
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||||
@ -782,8 +782,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f
|
|||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.10.0 h1:62NOS1h+r8p1mW6FM0FSB0exioXLhd/sh15KpjWBZ+8=
|
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo=
|
||||||
github.com/rs/cors v1.10.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
@ -883,12 +883,14 @@ github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8=
|
|||||||
github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||||
github.com/zitadel/logging v0.4.0 h1:lRAIFgaRoJpLNbsL7jtIYHcMDoEJP9QZB4GqMfl4xaA=
|
github.com/zitadel/logging v0.4.0 h1:lRAIFgaRoJpLNbsL7jtIYHcMDoEJP9QZB4GqMfl4xaA=
|
||||||
github.com/zitadel/logging v0.4.0/go.mod h1:6uALRJawpkkuUPCkgzfgcPR3c2N908wqnOnIrRelUFc=
|
github.com/zitadel/logging v0.4.0/go.mod h1:6uALRJawpkkuUPCkgzfgcPR3c2N908wqnOnIrRelUFc=
|
||||||
github.com/zitadel/oidc/v2 v2.11.0 h1:Am4/yQr4iiM5bznRgF3FOp+wLdKx2gzSU73uyI9vvBE=
|
github.com/zitadel/oidc/v3 v3.0.2 h1:fw0EAjx8lIlDMJ54hDz2fWIhpW/Y13tW5gd1qWGqbr4=
|
||||||
github.com/zitadel/oidc/v2 v2.11.0/go.mod h1:enFSVBQI6aE0TEB1ntjXs9r6O6DEosxX4uhEBLBVD8o=
|
github.com/zitadel/oidc/v3 v3.0.2/go.mod h1:ne9V9FHug4iUZDV42JirWVLHcbmwaxY8LnkcfekHgRg=
|
||||||
github.com/zitadel/passwap v0.4.0 h1:cMaISx+Ve7ilgG7Q8xOli4Z6IWr8Gndss+jeBk5A3O0=
|
github.com/zitadel/passwap v0.4.0 h1:cMaISx+Ve7ilgG7Q8xOli4Z6IWr8Gndss+jeBk5A3O0=
|
||||||
github.com/zitadel/passwap v0.4.0/go.mod h1:yHaDM4A68yRkdic5BZ4iUNoc19hT+kYt8n1/Nz+I87g=
|
github.com/zitadel/passwap v0.4.0/go.mod h1:yHaDM4A68yRkdic5BZ4iUNoc19hT+kYt8n1/Nz+I87g=
|
||||||
github.com/zitadel/saml v0.1.2 h1:RICwNTuP2upX4A1sZ8iq1rv4/x3DhZHzFx1e5bTKoTo=
|
github.com/zitadel/saml v0.1.2 h1:RICwNTuP2upX4A1sZ8iq1rv4/x3DhZHzFx1e5bTKoTo=
|
||||||
github.com/zitadel/saml v0.1.2/go.mod h1:M+X+3vMUulpoLofKeH/W1/qjQQ3owitc2GuGDu3oYpM=
|
github.com/zitadel/saml v0.1.2/go.mod h1:M+X+3vMUulpoLofKeH/W1/qjQQ3owitc2GuGDu3oYpM=
|
||||||
|
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
|
||||||
|
github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
@ -905,8 +907,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4
|
|||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0/go.mod h1:1WpsUwjQrUJSNugfMlPn0rPRJ9Do7wwBgTBPK7MLiS4=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.43.0/go.mod h1:1WpsUwjQrUJSNugfMlPn0rPRJ9Do7wwBgTBPK7MLiS4=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 h1:HKORGpiOY0R0nAPtKx/ub8/7XoHhRooP8yNRkuPfelI=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0 h1:HKORGpiOY0R0nAPtKx/ub8/7XoHhRooP8yNRkuPfelI=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0/go.mod h1:e+y1M74SYXo/FcIx3UATwth2+5dDkM8dBi7eXg1tbw8=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.43.0/go.mod h1:e+y1M74SYXo/FcIx3UATwth2+5dDkM8dBi7eXg1tbw8=
|
||||||
go.opentelemetry.io/otel v1.17.0 h1:MW+phZ6WZ5/uk2nd93ANk/6yJ+dVrvNWUjGhnnFU5jM=
|
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
|
||||||
go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0=
|
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 h1:U5GYackKpVKlPrd/5gKMlrTlP2dCESAAFU682VCpieY=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0 h1:U5GYackKpVKlPrd/5gKMlrTlP2dCESAAFU682VCpieY=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0/go.mod h1:aFsJfCEnLzEu9vRRAcUiB/cpRTbVsNdF3OHSPpdjxZQ=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.17.0/go.mod h1:aFsJfCEnLzEu9vRRAcUiB/cpRTbVsNdF3OHSPpdjxZQ=
|
||||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 h1:iGeIsSYwpYSvh5UGzWrJfTDJvPjrXtxl3GUppj6IXQU=
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.17.0 h1:iGeIsSYwpYSvh5UGzWrJfTDJvPjrXtxl3GUppj6IXQU=
|
||||||
@ -915,14 +917,14 @@ go.opentelemetry.io/otel/exporters/prometheus v0.40.0 h1:9h6lCssr1j5aYVvWT6oc+ER
|
|||||||
go.opentelemetry.io/otel/exporters/prometheus v0.40.0/go.mod h1:5USWZ0ovyQB5CIM3IO3bGRSoDPMXiT3t+15gu8Zo9HQ=
|
go.opentelemetry.io/otel/exporters/prometheus v0.40.0/go.mod h1:5USWZ0ovyQB5CIM3IO3bGRSoDPMXiT3t+15gu8Zo9HQ=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0 h1:Ut6hgtYcASHwCzRHkXEtSsM251cXJPW+Z9DyLwEn6iI=
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0 h1:Ut6hgtYcASHwCzRHkXEtSsM251cXJPW+Z9DyLwEn6iI=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0/go.mod h1:TYeE+8d5CjrgBa0ZuRaDeMpIC1xZ7atg4g+nInjuSjc=
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.17.0/go.mod h1:TYeE+8d5CjrgBa0ZuRaDeMpIC1xZ7atg4g+nInjuSjc=
|
||||||
go.opentelemetry.io/otel/metric v1.17.0 h1:iG6LGVz5Gh+IuO0jmgvpTB6YVrCGngi8QGm+pMd8Pdc=
|
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
|
||||||
go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o=
|
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
|
||||||
go.opentelemetry.io/otel/sdk v1.17.0 h1:FLN2X66Ke/k5Sg3V623Q7h7nt3cHXaW1FOvKKrW0IpE=
|
go.opentelemetry.io/otel/sdk v1.17.0 h1:FLN2X66Ke/k5Sg3V623Q7h7nt3cHXaW1FOvKKrW0IpE=
|
||||||
go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ=
|
go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.40.0 h1:qOM29YaGcxipWjL5FzpyZDpCYrDREvX0mVlmXdOjCHU=
|
go.opentelemetry.io/otel/sdk/metric v0.40.0 h1:qOM29YaGcxipWjL5FzpyZDpCYrDREvX0mVlmXdOjCHU=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.40.0/go.mod h1:dWxHtdzdJvg+ciJUKLTKwrMe5P6Dv3FyDbh8UkfgkVs=
|
go.opentelemetry.io/otel/sdk/metric v0.40.0/go.mod h1:dWxHtdzdJvg+ciJUKLTKwrMe5P6Dv3FyDbh8UkfgkVs=
|
||||||
go.opentelemetry.io/otel/trace v1.17.0 h1:/SWhSRHmDPOImIAetP1QAeMnZYiQXrTy4fMMYOdSKWQ=
|
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
|
||||||
go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY=
|
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
|
||||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||||
@ -952,6 +954,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
@ -965,8 +968,8 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0
|
|||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -1007,8 +1010,6 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
|
||||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -1059,8 +1060,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@ -1070,8 +1071,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
|
|||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
|
||||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -1154,8 +1155,8 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
@ -1242,8 +1243,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
|
|
||||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@ -1384,8 +1383,6 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a
|
|||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
83
internal/actions/uuid_module.go
Normal file
83
internal/actions/uuid_module.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package actions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/dop251/goja"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/zitadel/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithUUID(ctx context.Context) Option {
|
||||||
|
return func(c *runConfig) {
|
||||||
|
c.modules["zitadel/uuid"] = func(runtime *goja.Runtime, module *goja.Object) {
|
||||||
|
requireUUID(ctx, runtime, module)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func requireUUID(_ context.Context, runtime *goja.Runtime, module *goja.Object) {
|
||||||
|
o := module.Get("exports").(*goja.Object)
|
||||||
|
logging.OnError(o.Set("v1", inRuntime(uuid.NewUUID, runtime))).Warn("unable to set module")
|
||||||
|
logging.OnError(o.Set("v3", inRuntimeHash(uuid.NewMD5, runtime))).Warn("unable to set module")
|
||||||
|
logging.OnError(o.Set("v4", inRuntime(uuid.NewRandom, runtime))).Warn("unable to set module")
|
||||||
|
logging.OnError(o.Set("v5", inRuntimeHash(uuid.NewSHA1, runtime))).Warn("unable to set module")
|
||||||
|
logging.OnError(o.Set("namespaceDNS", uuid.NameSpaceDNS)).Warn("unable to set namespace")
|
||||||
|
logging.OnError(o.Set("namespaceURL", uuid.NameSpaceURL)).Warn("unable to set namespace")
|
||||||
|
logging.OnError(o.Set("namespaceOID", uuid.NameSpaceOID)).Warn("unable to set namespace")
|
||||||
|
logging.OnError(o.Set("namespaceX500", uuid.NameSpaceX500)).Warn("unable to set namespace")
|
||||||
|
}
|
||||||
|
|
||||||
|
func inRuntime(function func() (uuid.UUID, error), runtime *goja.Runtime) func(call goja.FunctionCall) goja.Value {
|
||||||
|
return func(call goja.FunctionCall) goja.Value {
|
||||||
|
if len(call.Arguments) != 0 {
|
||||||
|
panic("invalid arg count")
|
||||||
|
}
|
||||||
|
|
||||||
|
uuid, err := function()
|
||||||
|
if err != nil {
|
||||||
|
logging.WithError(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtime.ToValue(uuid.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func inRuntimeHash(function func(uuid.UUID, []byte) uuid.UUID, runtime *goja.Runtime) func(call goja.FunctionCall) goja.Value {
|
||||||
|
return func(call goja.FunctionCall) goja.Value {
|
||||||
|
if len(call.Arguments) != 2 {
|
||||||
|
logging.WithFields("count", len(call.Arguments)).Debug("other than 2 args provided")
|
||||||
|
panic("invalid arg count")
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var namespace uuid.UUID
|
||||||
|
switch n := call.Arguments[0].Export().(type) {
|
||||||
|
case string:
|
||||||
|
namespace, err = uuid.Parse(n)
|
||||||
|
if err != nil {
|
||||||
|
logging.WithError(err).Debug("namespace failed parsing as UUID")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
case uuid.UUID:
|
||||||
|
namespace = n
|
||||||
|
default:
|
||||||
|
logging.WithError(err).Debug("invalid type for namespace")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var data []byte
|
||||||
|
switch d := call.Arguments[1].Export().(type) {
|
||||||
|
case string:
|
||||||
|
data = []byte(d)
|
||||||
|
case []byte:
|
||||||
|
data = d
|
||||||
|
default:
|
||||||
|
logging.WithError(err).Debug("invalid type for data")
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return runtime.ToValue(function(namespace, data).String())
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/go-jose/go-jose/v3"
|
||||||
"gopkg.in/square/go-jose.v2"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
@ -28,7 +28,7 @@ type TokenVerifier struct {
|
|||||||
authZRepo authZRepo
|
authZRepo authZRepo
|
||||||
clients sync.Map
|
clients sync.Map
|
||||||
authMethods MethodMapping
|
authMethods MethodMapping
|
||||||
systemJWTProfile op.JWTProfileVerifier
|
systemJWTProfile *op.JWTProfileVerifier
|
||||||
}
|
}
|
||||||
|
|
||||||
type MembershipsResolver interface {
|
type MembershipsResolver interface {
|
||||||
|
@ -3,7 +3,7 @@ package management
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/api/http"
|
"github.com/zitadel/zitadel/internal/api/http"
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
|
||||||
@ -647,6 +647,26 @@ func (s *Server) RemoveHumanAuthFactorU2F(ctx context.Context, req *mgmt_pb.Remo
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) RemoveHumanAuthFactorOTPSMS(ctx context.Context, req *mgmt_pb.RemoveHumanAuthFactorOTPSMSRequest) (*mgmt_pb.RemoveHumanAuthFactorOTPSMSResponse, error) {
|
||||||
|
objectDetails, err := s.command.RemoveHumanOTPSMS(ctx, req.UserId, authz.GetCtxData(ctx).OrgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.RemoveHumanAuthFactorOTPSMSResponse{
|
||||||
|
Details: obj_grpc.DomainToChangeDetailsPb(objectDetails),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) RemoveHumanAuthFactorOTPEmail(ctx context.Context, req *mgmt_pb.RemoveHumanAuthFactorOTPEmailRequest) (*mgmt_pb.RemoveHumanAuthFactorOTPEmailResponse, error) {
|
||||||
|
objectDetails, err := s.command.RemoveHumanOTPEmail(ctx, req.UserId, authz.GetCtxData(ctx).OrgID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &mgmt_pb.RemoveHumanAuthFactorOTPEmailResponse{
|
||||||
|
Details: obj_grpc.DomainToChangeDetailsPb(objectDetails),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) ListHumanPasswordless(ctx context.Context, req *mgmt_pb.ListHumanPasswordlessRequest) (*mgmt_pb.ListHumanPasswordlessResponse, error) {
|
func (s *Server) ListHumanPasswordless(ctx context.Context, req *mgmt_pb.ListHumanPasswordlessRequest) (*mgmt_pb.ListHumanPasswordlessResponse, error) {
|
||||||
query := new(query.UserAuthMethodSearchQueries)
|
query := new(query.UserAuthMethodSearchQueries)
|
||||||
err := query.AppendUserIDQuery(req.UserId)
|
err := query.AppendUserIDQuery(req.UserId)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func TestServer_GetAuthRequest(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
client, err := Tester.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId())
|
client, err := Tester.CreateOIDCNativeClient(CTX, redirectURI, logoutRedirectURI, project.GetId())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ func TestServer_CreateCallback(t *testing.T) {
|
|||||||
name: "session not found",
|
name: "session not found",
|
||||||
req: &oidc_pb.CreateCallbackRequest{
|
req: &oidc_pb.CreateCallbackRequest{
|
||||||
AuthRequestId: func() string {
|
AuthRequestId: func() string {
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authRequestID
|
return authRequestID
|
||||||
}(),
|
}(),
|
||||||
@ -151,7 +151,7 @@ func TestServer_CreateCallback(t *testing.T) {
|
|||||||
name: "session token invalid",
|
name: "session token invalid",
|
||||||
req: &oidc_pb.CreateCallbackRequest{
|
req: &oidc_pb.CreateCallbackRequest{
|
||||||
AuthRequestId: func() string {
|
AuthRequestId: func() string {
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authRequestID
|
return authRequestID
|
||||||
}(),
|
}(),
|
||||||
@ -168,7 +168,7 @@ func TestServer_CreateCallback(t *testing.T) {
|
|||||||
name: "fail callback",
|
name: "fail callback",
|
||||||
req: &oidc_pb.CreateCallbackRequest{
|
req: &oidc_pb.CreateCallbackRequest{
|
||||||
AuthRequestId: func() string {
|
AuthRequestId: func() string {
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authRequestID
|
return authRequestID
|
||||||
}(),
|
}(),
|
||||||
@ -192,7 +192,7 @@ func TestServer_CreateCallback(t *testing.T) {
|
|||||||
name: "code callback",
|
name: "code callback",
|
||||||
req: &oidc_pb.CreateCallbackRequest{
|
req: &oidc_pb.CreateCallbackRequest{
|
||||||
AuthRequestId: func() string {
|
AuthRequestId: func() string {
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequest(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
authRequestID, err := Tester.CreateOIDCAuthRequest(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authRequestID
|
return authRequestID
|
||||||
}(),
|
}(),
|
||||||
@ -217,7 +217,7 @@ func TestServer_CreateCallback(t *testing.T) {
|
|||||||
AuthRequestId: func() string {
|
AuthRequestId: func() string {
|
||||||
client, err := Tester.CreateOIDCImplicitFlowClient(CTX, redirectURIImplicit)
|
client, err := Tester.CreateOIDCImplicitFlowClient(CTX, redirectURIImplicit)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID, err := Tester.CreateOIDCAuthRequestImplicit(client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURIImplicit)
|
authRequestID, err := Tester.CreateOIDCAuthRequestImplicit(CTX, client.GetClientId(), Tester.Users[integration.FirstInstanceUsersKey][integration.OrgOwner].ID, redirectURIImplicit)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return authRequestID
|
return authRequestID
|
||||||
}(),
|
}(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package oidc
|
package oidc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
@ -33,12 +33,7 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
|
|||||||
return nil, status.Error(codes.Unauthenticated, "auth header missing")
|
return nil, status.Error(codes.Unauthenticated, "auth header missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
var orgDomain string
|
orgID, orgDomain := orgIDAndDomainFromRequest(authCtx, req)
|
||||||
orgID := grpc_util.GetHeader(authCtx, http.ZitadelOrgID)
|
|
||||||
if o, ok := req.(OrganisationFromRequest); ok {
|
|
||||||
orgID = o.OrganisationFromRequest().ID
|
|
||||||
orgDomain = o.OrganisationFromRequest().Domain
|
|
||||||
}
|
|
||||||
ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod)
|
ctxSetter, err := authz.CheckUserAuthorization(authCtx, req, authToken, orgID, orgDomain, verifier, authConfig, authOpt, info.FullMethod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -47,11 +42,38 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
|
|||||||
return handler(ctxSetter(ctx), req)
|
return handler(ctxSetter(ctx), req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrganisationFromRequest interface {
|
func orgIDAndDomainFromRequest(ctx context.Context, req interface{}) (id, domain string) {
|
||||||
OrganisationFromRequest() *Organisation
|
orgID := grpc_util.GetHeader(ctx, http.ZitadelOrgID)
|
||||||
|
o, ok := req.(OrganizationFromRequest)
|
||||||
|
if !ok {
|
||||||
|
return orgID, ""
|
||||||
|
}
|
||||||
|
id = o.OrganizationFromRequest().ID
|
||||||
|
domain = o.OrganizationFromRequest().Domain
|
||||||
|
if id != "" || domain != "" {
|
||||||
|
return id, domain
|
||||||
|
}
|
||||||
|
// check if the deprecated organisation is used.
|
||||||
|
// to be removed before going GA (https://github.com/zitadel/zitadel/issues/6718)
|
||||||
|
id = o.OrganisationFromRequest().ID
|
||||||
|
domain = o.OrganisationFromRequest().Domain
|
||||||
|
if id != "" || domain != "" {
|
||||||
|
return id, domain
|
||||||
|
}
|
||||||
|
return orgID, domain
|
||||||
}
|
}
|
||||||
|
|
||||||
type Organisation struct {
|
// Deprecated: will be removed in favor of OrganizationFromRequest (https://github.com/zitadel/zitadel/issues/6718)
|
||||||
|
type OrganisationFromRequest interface {
|
||||||
|
OrganisationFromRequest() *Organization
|
||||||
|
}
|
||||||
|
|
||||||
|
type Organization struct {
|
||||||
ID string
|
ID string
|
||||||
Domain string
|
Domain string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrganizationFromRequest interface {
|
||||||
|
OrganizationFromRequest() *Organization
|
||||||
|
OrganisationFromRequest
|
||||||
|
}
|
||||||
|
@ -2,10 +2,13 @@ package session
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/known/structpb"
|
"google.golang.org/protobuf/types/known/structpb"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
|
"github.com/zitadel/zitadel/internal/api/grpc/object/v2"
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
@ -41,7 +44,7 @@ func (s *Server) ListSessions(ctx context.Context, req *session.ListSessionsRequ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) CreateSession(ctx context.Context, req *session.CreateSessionRequest) (*session.CreateSessionResponse, error) {
|
func (s *Server) CreateSession(ctx context.Context, req *session.CreateSessionRequest) (*session.CreateSessionResponse, error) {
|
||||||
checks, metadata, err := s.createSessionRequestToCommand(ctx, req)
|
checks, metadata, userAgent, err := s.createSessionRequestToCommand(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -50,7 +53,7 @@ func (s *Server) CreateSession(ctx context.Context, req *session.CreateSessionRe
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
set, err := s.command.CreateSession(ctx, cmds, metadata)
|
set, err := s.command.CreateSession(ctx, cmds, metadata, userAgent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -113,9 +116,34 @@ func sessionToPb(s *query.Session) *session.Session {
|
|||||||
Sequence: s.Sequence,
|
Sequence: s.Sequence,
|
||||||
Factors: factorsToPb(s),
|
Factors: factorsToPb(s),
|
||||||
Metadata: s.Metadata,
|
Metadata: s.Metadata,
|
||||||
|
UserAgent: userAgentToPb(s.UserAgent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func userAgentToPb(ua domain.UserAgent) *session.UserAgent {
|
||||||
|
if ua.IsEmpty() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
out := &session.UserAgent{
|
||||||
|
FingerprintId: ua.FingerprintID,
|
||||||
|
Description: ua.Description,
|
||||||
|
}
|
||||||
|
if ua.IP != nil {
|
||||||
|
out.Ip = gu.Ptr(ua.IP.String())
|
||||||
|
}
|
||||||
|
if ua.Header == nil {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
out.Header = make(map[string]*session.UserAgent_HeaderValues, len(ua.Header))
|
||||||
|
for k, v := range ua.Header {
|
||||||
|
out.Header[k] = &session.UserAgent_HeaderValues{
|
||||||
|
Values: v,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
func factorsToPb(s *query.Session) *session.Factors {
|
func factorsToPb(s *query.Session) *session.Factors {
|
||||||
user := userFactorToPb(s.UserFactor)
|
user := userFactorToPb(s.UserFactor)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
@ -188,6 +216,7 @@ func userFactorToPb(factor query.SessionUserFactor) *session.UserFactor {
|
|||||||
LoginName: factor.LoginName,
|
LoginName: factor.LoginName,
|
||||||
DisplayName: factor.DisplayName,
|
DisplayName: factor.DisplayName,
|
||||||
OrganisationId: factor.ResourceOwner,
|
OrganisationId: factor.ResourceOwner,
|
||||||
|
OrganizationId: factor.ResourceOwner,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,12 +265,30 @@ func idsQueryToQuery(q *session.IDsQuery) (query.SearchQuery, error) {
|
|||||||
return query.NewSessionIDsSearchQuery(q.Ids)
|
return query.NewSessionIDsSearchQuery(q.Ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) createSessionRequestToCommand(ctx context.Context, req *session.CreateSessionRequest) ([]command.SessionCommand, map[string][]byte, error) {
|
func (s *Server) createSessionRequestToCommand(ctx context.Context, req *session.CreateSessionRequest) ([]command.SessionCommand, map[string][]byte, *domain.UserAgent, error) {
|
||||||
checks, err := s.checksToCommand(ctx, req.Checks)
|
checks, err := s.checksToCommand(ctx, req.Checks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
return checks, req.GetMetadata(), nil
|
return checks, req.GetMetadata(), userAgentToCommand(req.GetUserAgent()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func userAgentToCommand(userAgent *session.UserAgent) *domain.UserAgent {
|
||||||
|
if userAgent == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := &domain.UserAgent{
|
||||||
|
FingerprintID: userAgent.FingerprintId,
|
||||||
|
IP: net.ParseIP(userAgent.GetIp()),
|
||||||
|
Description: userAgent.Description,
|
||||||
|
}
|
||||||
|
if len(userAgent.Header) > 0 {
|
||||||
|
out.Header = make(http.Header, len(userAgent.Header))
|
||||||
|
for k, values := range userAgent.Header {
|
||||||
|
out.Header[k] = values.GetValues()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) setSessionRequestToCommand(ctx context.Context, req *session.SetSessionRequest) ([]command.SessionCommand, error) {
|
func (s *Server) setSessionRequestToCommand(ctx context.Context, req *session.SetSessionRequest) ([]command.SessionCommand, error) {
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/integration"
|
"github.com/zitadel/zitadel/internal/integration"
|
||||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
object "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
|
||||||
@ -53,7 +54,7 @@ func TestMain(m *testing.M) {
|
|||||||
}())
|
}())
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, window time.Duration, metadata map[string][]byte, factors ...wantFactor) *session.Session {
|
func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, window time.Duration, metadata map[string][]byte, userAgent *session.UserAgent, factors ...wantFactor) *session.Session {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
require.NotEmpty(t, id)
|
require.NotEmpty(t, id)
|
||||||
require.NotEmpty(t, token)
|
require.NotEmpty(t, token)
|
||||||
@ -70,6 +71,11 @@ func verifyCurrentSession(t testing.TB, id, token string, sequence uint64, windo
|
|||||||
assert.WithinRange(t, s.GetChangeDate().AsTime(), time.Now().Add(-window), time.Now().Add(window))
|
assert.WithinRange(t, s.GetChangeDate().AsTime(), time.Now().Add(-window), time.Now().Add(window))
|
||||||
assert.Equal(t, sequence, s.GetSequence())
|
assert.Equal(t, sequence, s.GetSequence())
|
||||||
assert.Equal(t, metadata, s.GetMetadata())
|
assert.Equal(t, metadata, s.GetMetadata())
|
||||||
|
|
||||||
|
if !proto.Equal(userAgent, s.GetUserAgent()) {
|
||||||
|
t.Errorf("user agent =\n%v\nwant\n%v", s.GetUserAgent(), userAgent)
|
||||||
|
}
|
||||||
|
|
||||||
verifyFactors(t, s.GetFactors(), window, factors)
|
verifyFactors(t, s.GetFactors(), window, factors)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -131,11 +137,12 @@ func verifyFactors(t testing.TB, factors *session.Factors, window time.Duration,
|
|||||||
|
|
||||||
func TestServer_CreateSession(t *testing.T) {
|
func TestServer_CreateSession(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
req *session.CreateSessionRequest
|
req *session.CreateSessionRequest
|
||||||
want *session.CreateSessionResponse
|
want *session.CreateSessionResponse
|
||||||
wantErr bool
|
wantErr bool
|
||||||
wantFactors []wantFactor
|
wantFactors []wantFactor
|
||||||
|
wantUserAgent *session.UserAgent
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty session",
|
name: "empty session",
|
||||||
@ -148,6 +155,33 @@ func TestServer_CreateSession(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "user agent",
|
||||||
|
req: &session.CreateSessionRequest{
|
||||||
|
Metadata: map[string][]byte{"foo": []byte("bar")},
|
||||||
|
UserAgent: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerPrintID"),
|
||||||
|
Ip: gu.Ptr("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("Description"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"foo": {Values: []string{"foo", "bar"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: &session.CreateSessionResponse{
|
||||||
|
Details: &object.Details{
|
||||||
|
ResourceOwner: Tester.Organisation.ID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantUserAgent: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerPrintID"),
|
||||||
|
Ip: gu.Ptr("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("Description"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"foo": {Values: []string{"foo", "bar"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "with user",
|
name: "with user",
|
||||||
req: &session.CreateSessionRequest{
|
req: &session.CreateSessionRequest{
|
||||||
@ -219,7 +253,7 @@ func TestServer_CreateSession(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
integration.AssertDetails(t, tt.want, got)
|
integration.AssertDetails(t, tt.want, got)
|
||||||
|
|
||||||
verifyCurrentSession(t, got.GetSessionId(), got.GetSessionToken(), got.GetDetails().GetSequence(), time.Minute, tt.req.GetMetadata(), tt.wantFactors...)
|
verifyCurrentSession(t, got.GetSessionId(), got.GetSessionToken(), got.GetDetails().GetSequence(), time.Minute, tt.req.GetMetadata(), tt.wantUserAgent, tt.wantFactors...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,7 +276,7 @@ func TestServer_CreateSession_webauthn(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
|
|
||||||
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(createResp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true)
|
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(createResp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -258,7 +292,7 @@ func TestServer_CreateSession_webauthn(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactorUserVerified)
|
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactorUserVerified)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
||||||
@ -274,7 +308,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
|
|
||||||
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id")
|
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, User.GetUserId(), "id")
|
||||||
updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{
|
updateResp, err := Client.SetSession(CTX, &session.SetSessionRequest{
|
||||||
@ -288,7 +322,7 @@ func TestServer_CreateSession_successfulIntent(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantIntentFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantIntentFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
||||||
@ -304,7 +338,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
|
|
||||||
idpUserID := "id"
|
idpUserID := "id"
|
||||||
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, "", idpUserID)
|
intentID, token, _, _ := Tester.CreateSuccessfulOAuthIntent(t, idpID, "", idpUserID)
|
||||||
@ -331,7 +365,7 @@ func TestServer_CreateSession_successfulIntentUnknownUserID(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantIntentFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), updateResp.GetSessionToken(), updateResp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantIntentFactor)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
|
func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
|
||||||
@ -347,7 +381,7 @@ func TestServer_CreateSession_startedIntentFalseToken(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), createResp.GetSessionToken(), createResp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
|
|
||||||
intentID := Tester.CreateIntent(t, idpID)
|
intentID := Tester.CreateIntent(t, idpID)
|
||||||
_, err = Client.SetSession(CTX, &session.SetSessionRequest{
|
_, err = Client.SetSession(CTX, &session.SetSessionRequest{
|
||||||
@ -399,7 +433,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{})
|
createResp, err := Client.CreateSession(CTX, &session.CreateSessionRequest{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken := createResp.GetSessionToken()
|
sessionToken := createResp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, createResp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, createResp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
|
|
||||||
t.Run("check user", func(t *testing.T) {
|
t.Run("check user", func(t *testing.T) {
|
||||||
resp, err := Client.SetSession(CTX, &session.SetSessionRequest{
|
resp, err := Client.SetSession(CTX, &session.SetSessionRequest{
|
||||||
@ -415,7 +449,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("check webauthn, user verified (passkey)", func(t *testing.T) {
|
t.Run("check webauthn, user verified (passkey)", func(t *testing.T) {
|
||||||
@ -430,7 +464,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
|
|
||||||
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true)
|
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), true)
|
||||||
@ -447,7 +481,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactorUserVerified)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactorUserVerified)
|
||||||
})
|
})
|
||||||
|
|
||||||
userAuthCtx := Tester.WithAuthorizationToken(CTX, sessionToken)
|
userAuthCtx := Tester.WithAuthorizationToken(CTX, sessionToken)
|
||||||
@ -474,7 +508,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
|
|
||||||
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), false)
|
assertionData, err := Tester.WebAuthN.CreateAssertionResponse(resp.GetChallenges().GetWebAuthN().GetPublicKeyCredentialRequestOptions(), false)
|
||||||
@ -491,7 +525,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -510,7 +544,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantTOTPFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantTOTPFactor)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("check OTP SMS", func(t *testing.T) {
|
t.Run("check OTP SMS", func(t *testing.T) {
|
||||||
@ -522,7 +556,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
|
|
||||||
otp := resp.GetChallenges().GetOtpSms()
|
otp := resp.GetChallenges().GetOtpSms()
|
||||||
@ -539,7 +573,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantOTPSMSFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantOTPSMSFactor)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("check OTP Email", func(t *testing.T) {
|
t.Run("check OTP Email", func(t *testing.T) {
|
||||||
@ -553,7 +587,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil)
|
verifyCurrentSession(t, createResp.GetSessionId(), resp.GetSessionToken(), resp.GetDetails().GetSequence(), time.Minute, nil, nil)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
|
|
||||||
otp := resp.GetChallenges().GetOtpEmail()
|
otp := resp.GetChallenges().GetOtpEmail()
|
||||||
@ -570,7 +604,7 @@ func TestServer_SetSession_flow(t *testing.T) {
|
|||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
sessionToken = resp.GetSessionToken()
|
sessionToken = resp.GetSessionToken()
|
||||||
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, wantUserFactor, wantWebAuthNFactor, wantOTPEmailFactor)
|
verifyCurrentSession(t, createResp.GetSessionId(), sessionToken, resp.GetDetails().GetSequence(), time.Minute, nil, nil, wantUserFactor, wantWebAuthNFactor, wantOTPEmailFactor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,19 @@ package session
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
caos_errs "github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
@ -23,7 +27,7 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
past := now.Add(-time.Hour)
|
past := now.Add(-time.Hour)
|
||||||
|
|
||||||
sessions := []*query.Session{
|
sessions := []*query.Session{
|
||||||
{ // no factor
|
{ // no factor, with user agent
|
||||||
ID: "999",
|
ID: "999",
|
||||||
CreationDate: now,
|
CreationDate: now,
|
||||||
ChangeDate: now,
|
ChangeDate: now,
|
||||||
@ -32,6 +36,12 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
ResourceOwner: "me",
|
ResourceOwner: "me",
|
||||||
Creator: "he",
|
Creator: "he",
|
||||||
Metadata: map[string][]byte{"hello": []byte("world")},
|
Metadata: map[string][]byte{"hello": []byte("world")},
|
||||||
|
UserAgent: domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fingerprintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
|
Header: http.Header{"foo": []string{"foo", "bar"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ // user factor
|
{ // user factor
|
||||||
ID: "999",
|
ID: "999",
|
||||||
@ -114,13 +124,21 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
want := []*session.Session{
|
want := []*session.Session{
|
||||||
{ // no factor
|
{ // no factor, with user agent
|
||||||
Id: "999",
|
Id: "999",
|
||||||
CreationDate: timestamppb.New(now),
|
CreationDate: timestamppb.New(now),
|
||||||
ChangeDate: timestamppb.New(now),
|
ChangeDate: timestamppb.New(now),
|
||||||
Sequence: 123,
|
Sequence: 123,
|
||||||
Factors: nil,
|
Factors: nil,
|
||||||
Metadata: map[string][]byte{"hello": []byte("world")},
|
Metadata: map[string][]byte{"hello": []byte("world")},
|
||||||
|
UserAgent: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerprintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
Ip: gu.Ptr("1.2.3.4"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"foo": {Values: []string{"foo", "bar"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ // user factor
|
{ // user factor
|
||||||
Id: "999",
|
Id: "999",
|
||||||
@ -134,6 +152,7 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
LoginName: "donald",
|
LoginName: "donald",
|
||||||
DisplayName: "donald duck",
|
DisplayName: "donald duck",
|
||||||
OrganisationId: "org1",
|
OrganisationId: "org1",
|
||||||
|
OrganizationId: "org1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Metadata: map[string][]byte{"hello": []byte("world")},
|
Metadata: map[string][]byte{"hello": []byte("world")},
|
||||||
@ -150,6 +169,7 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
LoginName: "donald",
|
LoginName: "donald",
|
||||||
DisplayName: "donald duck",
|
DisplayName: "donald duck",
|
||||||
OrganisationId: "org1",
|
OrganisationId: "org1",
|
||||||
|
OrganizationId: "org1",
|
||||||
},
|
},
|
||||||
Password: &session.PasswordFactor{
|
Password: &session.PasswordFactor{
|
||||||
VerifiedAt: timestamppb.New(past),
|
VerifiedAt: timestamppb.New(past),
|
||||||
@ -169,6 +189,7 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
LoginName: "donald",
|
LoginName: "donald",
|
||||||
DisplayName: "donald duck",
|
DisplayName: "donald duck",
|
||||||
OrganisationId: "org1",
|
OrganisationId: "org1",
|
||||||
|
OrganizationId: "org1",
|
||||||
},
|
},
|
||||||
WebAuthN: &session.WebAuthNFactor{
|
WebAuthN: &session.WebAuthNFactor{
|
||||||
VerifiedAt: timestamppb.New(past),
|
VerifiedAt: timestamppb.New(past),
|
||||||
@ -189,6 +210,7 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
LoginName: "donald",
|
LoginName: "donald",
|
||||||
DisplayName: "donald duck",
|
DisplayName: "donald duck",
|
||||||
OrganisationId: "org1",
|
OrganisationId: "org1",
|
||||||
|
OrganizationId: "org1",
|
||||||
},
|
},
|
||||||
Totp: &session.TOTPFactor{
|
Totp: &session.TOTPFactor{
|
||||||
VerifiedAt: timestamppb.New(past),
|
VerifiedAt: timestamppb.New(past),
|
||||||
@ -208,6 +230,71 @@ func Test_sessionsToPb(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_userAgentToPb(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
ua domain.UserAgent
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *session.UserAgent
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
args: args{domain.UserAgent{}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "fingerprint id and description",
|
||||||
|
args: args{domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
}},
|
||||||
|
want: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with ip",
|
||||||
|
args: args{domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
|
}},
|
||||||
|
want: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
Ip: gu.Ptr("1.2.3.4"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with header",
|
||||||
|
args: args{domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
Header: http.Header{
|
||||||
|
"foo": []string{"foo", "bar"},
|
||||||
|
"hello": []string{"world"},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
want: &session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fingerPrintID"),
|
||||||
|
Description: gu.Ptr("description"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"foo": {Values: []string{"foo", "bar"}},
|
||||||
|
"hello": {Values: []string{"world"}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := userAgentToPb(tt.args.ua)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func mustNewTextQuery(t testing.TB, column query.Column, value string, compare query.TextComparison) query.SearchQuery {
|
func mustNewTextQuery(t testing.TB, column query.Column, value string, compare query.TextComparison) query.SearchQuery {
|
||||||
q, err := query.NewTextQuery(column, value, compare)
|
q, err := query.NewTextQuery(column, value, compare)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -510,3 +597,73 @@ func Test_userVerificationRequirementToDomain(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_userAgentToCommand(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
userAgent *session.UserAgent
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want *domain.UserAgent
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil",
|
||||||
|
args: args{nil},
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all fields",
|
||||||
|
args: args{&session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fp1"),
|
||||||
|
Ip: gu.Ptr("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"hello": {
|
||||||
|
Values: []string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
want: &domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{
|
||||||
|
"hello": []string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid ip",
|
||||||
|
args: args{&session.UserAgent{
|
||||||
|
FingerprintId: gu.Ptr("fp1"),
|
||||||
|
Ip: gu.Ptr("oops"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: map[string]*session.UserAgent_HeaderValues{
|
||||||
|
"hello": {
|
||||||
|
Values: []string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
want: &domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: nil,
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{
|
||||||
|
"hello": []string{"foo", "bar"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nil fields",
|
||||||
|
args: args{&session.UserAgent{}},
|
||||||
|
want: &domain.UserAgent{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := userAgentToCommand(tt.args.userAgent)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@ package system
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/authn"
|
"github.com/zitadel/zitadel/internal/api/grpc/authn"
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
@ -3,7 +3,7 @@ package oidc
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
)
|
)
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
"github.com/muhlemmer/gu"
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
||||||
oidc_api "github.com/zitadel/zitadel/internal/api/oidc"
|
oidc_api "github.com/zitadel/zitadel/internal/api/oidc"
|
||||||
@ -103,7 +103,7 @@ func TestOPStorage_CreateAccessToken_implicit(t *testing.T) {
|
|||||||
assert.Equal(t, "state", values.Get("state"))
|
assert.Equal(t, "state", values.Get("state"))
|
||||||
|
|
||||||
// check id_token / claims
|
// check id_token / claims
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURIImplicit)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURIImplicit)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), accessToken, idToken, provider.IDTokenVerifier())
|
claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), accessToken, idToken, provider.IDTokenVerifier())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -147,7 +147,7 @@ func TestOPStorage_CreateAccessAndRefreshTokens_code(t *testing.T) {
|
|||||||
|
|
||||||
func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) {
|
func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -177,13 +177,13 @@ func TestOPStorage_CreateAccessAndRefreshTokens_refresh(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, newTokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, newTokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// refresh with an old refresh_token must fail
|
// refresh with an old refresh_token must fail
|
||||||
_, err = rp.RefreshAccessToken(provider, tokens.RefreshToken, "", "")
|
_, err = rp.RefreshTokens[*oidc.IDTokenClaims](CTX, provider, tokens.RefreshToken, "", "")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_RevokeToken_access_token(t *testing.T) {
|
func TestOPStorage_RevokeToken_access_token(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -206,11 +206,11 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// revoke access token
|
// revoke access token
|
||||||
err = rp.RevokeToken(provider, tokens.AccessToken, "access_token")
|
err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "access_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// refresh grant must still work
|
// refresh grant must still work
|
||||||
@ -218,15 +218,15 @@ func TestOPStorage_RevokeToken_access_token(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// revocation with the same access token must not fail (with or without hint)
|
// revocation with the same access token must not fail (with or without hint)
|
||||||
err = rp.RevokeToken(provider, tokens.AccessToken, "access_token")
|
err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "access_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = rp.RevokeToken(provider, tokens.AccessToken, "")
|
err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T) {
|
func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -249,11 +249,11 @@ func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// revoke access token
|
// revoke access token
|
||||||
err = rp.RevokeToken(provider, tokens.AccessToken, "refresh_token")
|
err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "refresh_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// refresh grant must still work
|
// refresh grant must still work
|
||||||
@ -263,7 +263,7 @@ func TestOPStorage_RevokeToken_access_token_invalid_token_hint_type(t *testing.T
|
|||||||
|
|
||||||
func TestOPStorage_RevokeToken_refresh_token(t *testing.T) {
|
func TestOPStorage_RevokeToken_refresh_token(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -286,11 +286,11 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// revoke refresh token -> invalidates also access token
|
// revoke refresh token -> invalidates also access token
|
||||||
err = rp.RevokeToken(provider, tokens.RefreshToken, "refresh_token")
|
err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "refresh_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// refresh must fail
|
// refresh must fail
|
||||||
@ -298,15 +298,15 @@ func TestOPStorage_RevokeToken_refresh_token(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// revocation with the same refresh token must not fail (with or without hint)
|
// revocation with the same refresh token must not fail (with or without hint)
|
||||||
err = rp.RevokeToken(provider, tokens.RefreshToken, "refresh_token")
|
err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "refresh_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = rp.RevokeToken(provider, tokens.RefreshToken, "")
|
err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing.T) {
|
func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -329,11 +329,11 @@ func TestOPStorage_RevokeToken_refresh_token_invalid_token_type_hint(t *testing.
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// revoke refresh token even with a wrong hint
|
// revoke refresh token even with a wrong hint
|
||||||
err = rp.RevokeToken(provider, tokens.RefreshToken, "access_token")
|
err = rp.RevokeToken(CTX, provider, tokens.RefreshToken, "access_token")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
// refresh must fail
|
// refresh must fail
|
||||||
@ -365,15 +365,15 @@ func TestOPStorage_RevokeToken_invalid_client(t *testing.T) {
|
|||||||
|
|
||||||
// simulate second client (not part of the audience) trying to revoke the token
|
// simulate second client (not part of the audience) trying to revoke the token
|
||||||
otherClientID := createClient(t)
|
otherClientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(otherClientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, otherClientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = rp.RevokeToken(provider, tokens.AccessToken, "")
|
err = rp.RevokeToken(CTX, provider, tokens.AccessToken, "")
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_TerminateSession(t *testing.T) {
|
func TestOPStorage_TerminateSession(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI)
|
authRequestID := createAuthRequest(t, clientID, redirectURI)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -396,21 +396,21 @@ func TestOPStorage_TerminateSession(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// userinfo must not fail
|
// userinfo must not fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state")
|
postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) {
|
func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -433,28 +433,28 @@ func TestOPStorage_TerminateSession_refresh_grant(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// userinfo must not fail
|
// userinfo must not fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state")
|
postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
||||||
refreshedTokens, err := refreshTokens(t, clientID, tokens.RefreshToken)
|
refreshedTokens, err := refreshTokens(t, clientID, tokens.RefreshToken)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must not fail
|
// userinfo must not fail
|
||||||
_, err = rp.Userinfo(refreshedTokens.AccessToken, refreshedTokens.TokenType, refreshedTokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, refreshedTokens.AccessToken, refreshedTokens.TokenType, refreshedTokens.IDTokenClaims.Subject, provider)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) {
|
func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI)
|
authRequestID := createAuthRequest(t, clientID, redirectURI)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -476,12 +476,12 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) {
|
|||||||
assertTokens(t, tokens, false)
|
assertTokens(t, tokens, false)
|
||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
postLogoutRedirect, err := rp.EndSession(provider, "", logoutRedirectURI, "state")
|
postLogoutRedirect, err := rp.EndSession(CTX, provider, "", logoutRedirectURI, "state")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http_utils.BuildOrigin(Tester.Host(), Tester.Config.ExternalSecure)+Tester.Config.OIDC.DefaultLogoutURLV2+logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
assert.Equal(t, http_utils.BuildOrigin(Tester.Host(), Tester.Config.ExternalSecure)+Tester.Config.OIDC.DefaultLogoutURLV2+logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
||||||
|
|
||||||
// userinfo must not fail until login UI terminated session
|
// userinfo must not fail until login UI terminated session
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// simulate termination by login UI
|
// simulate termination by login UI
|
||||||
@ -492,12 +492,12 @@ func TestOPStorage_TerminateSession_empty_id_token_hint(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// userinfo must fail
|
// userinfo must fail
|
||||||
_, err = rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
_, err = rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func exchangeTokens(t testing.TB, clientID, code string) (*oidc.Tokens[*oidc.IDTokenClaims], error) {
|
func exchangeTokens(t testing.TB, clientID, code string) (*oidc.Tokens[*oidc.IDTokenClaims], error) {
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
codeVerifier := "codeVerifier"
|
codeVerifier := "codeVerifier"
|
||||||
@ -505,23 +505,10 @@ func exchangeTokens(t testing.TB, clientID, code string) (*oidc.Tokens[*oidc.IDT
|
|||||||
}
|
}
|
||||||
|
|
||||||
func refreshTokens(t testing.TB, clientID, refreshToken string) (*oidc.Tokens[*oidc.IDTokenClaims], error) {
|
func refreshTokens(t testing.TB, clientID, refreshToken string) (*oidc.Tokens[*oidc.IDTokenClaims], error) {
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
tokens, err := rp.RefreshAccessToken(provider, refreshToken, "", "")
|
return rp.RefreshTokens[*oidc.IDTokenClaims](CTX, provider, refreshToken, "", "")
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
idToken, _ := tokens.Extra("id_token").(string)
|
|
||||||
claims, err := rp.VerifyTokens[*oidc.IDTokenClaims](context.Background(), tokens.AccessToken, idToken, provider.IDTokenVerifier())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &oidc.Tokens[*oidc.IDTokenClaims]{
|
|
||||||
Token: tokens,
|
|
||||||
IDToken: idToken,
|
|
||||||
IDTokenClaims: claims,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertCodeResponse(t *testing.T, callback string) string {
|
func assertCodeResponse(t *testing.T, callback string) string {
|
||||||
|
@ -9,10 +9,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/actions"
|
"github.com/zitadel/zitadel/internal/actions"
|
||||||
"github.com/zitadel/zitadel/internal/actions/object"
|
"github.com/zitadel/zitadel/internal/actions/object"
|
||||||
@ -564,7 +564,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, user *query.User, userGra
|
|||||||
apiFields,
|
apiFields,
|
||||||
action.Script,
|
action.Script,
|
||||||
action.Name,
|
action.Name,
|
||||||
append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -745,7 +745,7 @@ func (o *OPStorage) privateClaimsFlows(ctx context.Context, userID string, userG
|
|||||||
apiFields,
|
apiFields,
|
||||||
action.Script,
|
action.Script,
|
||||||
action.Name,
|
action.Name,
|
||||||
append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(action), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -3,8 +3,8 @@ package oidc
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
)
|
)
|
||||||
|
|
||||||
type clientCredentialsRequest struct {
|
type clientCredentialsRequest struct {
|
||||||
|
@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rs"
|
"github.com/zitadel/oidc/v3/pkg/client/rs"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/pkg/grpc/authn"
|
"github.com/zitadel/zitadel/pkg/grpc/authn"
|
||||||
"github.com/zitadel/zitadel/pkg/grpc/management"
|
"github.com/zitadel/zitadel/pkg/grpc/management"
|
||||||
@ -41,9 +41,9 @@ func TestOPStorage_SetUserinfoFromToken(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// test actual userinfo
|
// test actual userinfo
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
userinfo, err := rp.Userinfo(tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
userinfo, err := rp.Userinfo[*oidc.UserInfo](CTX, tokens.AccessToken, tokens.TokenType, tokens.IDTokenClaims.Subject, provider)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertUserinfo(t, userinfo)
|
assertUserinfo(t, userinfo)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ func TestOPStorage_SetIntrospectionFromToken(t *testing.T) {
|
|||||||
ExpirationDate: nil,
|
ExpirationDate: nil,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
resourceServer, err := Tester.CreateResourceServer(keyResp.GetKeyDetails())
|
resourceServer, err := Tester.CreateResourceServer(CTX, keyResp.GetKeyDetails())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
scope := []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopeOfflineAccess}
|
scope := []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopeOfflineAccess}
|
||||||
@ -87,7 +87,7 @@ func TestOPStorage_SetIntrospectionFromToken(t *testing.T) {
|
|||||||
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
assertIDTokenClaims(t, tokens.IDTokenClaims, armPasskey, startTime, changeTime)
|
||||||
|
|
||||||
// test actual introspection
|
// test actual introspection
|
||||||
introspection, err := rs.Introspect(context.Background(), resourceServer, tokens.AccessToken)
|
introspection, err := rs.Introspect[*oidc.IntrospectionResponse](context.Background(), resourceServer, tokens.AccessToken)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assertIntrospection(t, introspection,
|
assertIntrospection(t, introspection,
|
||||||
Tester.OIDCIssuer(), app.GetClientId(),
|
Tester.OIDCIssuer(), app.GetClientId(),
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/ui/login"
|
"github.com/zitadel/zitadel/internal/api/ui/login"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -3,8 +3,8 @@ package oidc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
@ -11,8 +11,8 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
@ -216,7 +216,7 @@ func Test_ZITADEL_API_inactive_access_token(t *testing.T) {
|
|||||||
|
|
||||||
func Test_ZITADEL_API_terminated_session(t *testing.T) {
|
func Test_ZITADEL_API_terminated_session(t *testing.T) {
|
||||||
clientID := createClient(t)
|
clientID := createClient(t)
|
||||||
provider, err := Tester.CreateRelyingParty(clientID, redirectURI)
|
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope)
|
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope)
|
||||||
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerfiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
|
||||||
@ -245,7 +245,7 @@ func Test_ZITADEL_API_terminated_session(t *testing.T) {
|
|||||||
require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId())
|
require.Equal(t, User.GetUserId(), myUserResp.GetUser().GetId())
|
||||||
|
|
||||||
// refresh token
|
// refresh token
|
||||||
postLogoutRedirect, err := rp.EndSession(provider, tokens.IDToken, logoutRedirectURI, "state")
|
postLogoutRedirect, err := rp.EndSession(CTX, provider, tokens.IDToken, logoutRedirectURI, "state")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
assert.Equal(t, logoutRedirectURI+"?state=state", postLogoutRedirect.String())
|
||||||
|
|
||||||
@ -271,13 +271,13 @@ func createImplicitClient(t testing.TB) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createAuthRequest(t testing.TB, clientID, redirectURI string, scope ...string) string {
|
func createAuthRequest(t testing.TB, clientID, redirectURI string, scope ...string) string {
|
||||||
redURL, err := Tester.CreateOIDCAuthRequest(clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...)
|
redURL, err := Tester.CreateOIDCAuthRequest(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return redURL
|
return redURL
|
||||||
}
|
}
|
||||||
|
|
||||||
func createAuthRequestImplicit(t testing.TB, clientID, redirectURI string, scope ...string) string {
|
func createAuthRequestImplicit(t testing.TB, clientID, redirectURI string, scope ...string) string {
|
||||||
redURL, err := Tester.CreateOIDCAuthRequestImplicit(clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...)
|
redURL, err := Tester.CreateOIDCAuthRequestImplicit(CTX, clientID, Tester.Users[integration.FirstInstanceUsersKey][integration.Login].ID, redirectURI, scope...)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return redURL
|
return redURL
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rakyll/statik/fs"
|
"github.com/rakyll/statik/fs"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/assets"
|
"github.com/zitadel/zitadel/internal/api/assets"
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/saml/pkg/provider/key"
|
"github.com/zitadel/saml/pkg/provider/key"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/cmd/build"
|
"github.com/zitadel/zitadel/cmd/build"
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/dop251/goja"
|
"github.com/dop251/goja"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/actions"
|
"github.com/zitadel/zitadel/internal/actions"
|
||||||
@ -133,7 +133,7 @@ func (l *Login) runPostExternalAuthenticationActions(
|
|||||||
apiFields,
|
apiFields,
|
||||||
a.Script,
|
a.Script,
|
||||||
a.Name,
|
a.Name,
|
||||||
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -206,7 +206,7 @@ func (l *Login) runPostInternalAuthenticationActions(
|
|||||||
apiFields,
|
apiFields,
|
||||||
a.Script,
|
a.Script,
|
||||||
a.Name,
|
a.Name,
|
||||||
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -307,7 +307,7 @@ func (l *Login) runPreCreationActions(
|
|||||||
apiFields,
|
apiFields,
|
||||||
a.Script,
|
a.Script,
|
||||||
a.Name,
|
a.Name,
|
||||||
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -365,7 +365,7 @@ func (l *Login) runPostCreationActions(
|
|||||||
apiFields,
|
apiFields,
|
||||||
a.Script,
|
a.Script,
|
||||||
a.Name,
|
a.Name,
|
||||||
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx))...,
|
append(actions.ActionToOptions(a), actions.WithHTTP(actionCtx), actions.WithUUID(actionCtx))...,
|
||||||
)
|
)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
"github.com/crewjam/saml/samlsp"
|
"github.com/crewjam/saml/samlsp"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
|
@ -7,10 +7,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v2/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
@ -274,7 +274,7 @@ func (repo *TokenVerifierRepo) getTokenIDAndSubject(ctx context.Context, accessT
|
|||||||
return splitToken[0], splitToken[1], true
|
return splitToken[0], splitToken[1], true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *TokenVerifierRepo) jwtTokenVerifier(ctx context.Context) op.AccessTokenVerifier {
|
func (repo *TokenVerifierRepo) jwtTokenVerifier(ctx context.Context) *op.AccessTokenVerifier {
|
||||||
keySet := &openIDKeySet{repo.Query}
|
keySet := &openIDKeySet{repo.Query}
|
||||||
issuer := http_util.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), repo.ExternalSecure)
|
issuer := http_util.BuildOrigin(authz.GetInstance(ctx).RequestedHost(), repo.ExternalSecure)
|
||||||
return op.NewAccessTokenVerifier(issuer, keySet)
|
return op.NewAccessTokenVerifier(issuer, keySet)
|
||||||
|
@ -2,6 +2,8 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -354,7 +356,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(mockCtx,
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) {
|
tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) {
|
||||||
@ -397,7 +407,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(mockCtx,
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) {
|
tokenVerifier: func(ctx context.Context, sessionToken, sessionID, tokenID string) (err error) {
|
||||||
@ -440,8 +458,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate),
|
session.NewAddedEvent(mockCtx,
|
||||||
),
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"userID", testNow),
|
"userID", testNow),
|
||||||
@ -517,8 +542,15 @@ func TestCommands_LinkSessionToAuthRequest(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate),
|
session.NewAddedEvent(mockCtx,
|
||||||
),
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewUserCheckedEvent(mockCtx, &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"userID", testNow),
|
"userID", testNow),
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/crewjam/saml"
|
"github.com/crewjam/saml"
|
||||||
"github.com/crewjam/saml/samlsp"
|
"github.com/crewjam/saml/samlsp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/command/preparation"
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
|
@ -2,6 +2,8 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -163,7 +165,15 @@ func TestCommands_AddOIDCSessionAccessToken(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate,
|
session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate,
|
||||||
@ -356,7 +366,15 @@ func TestCommands_AddOIDCSessionRefreshAndAccessToken(t *testing.T) {
|
|||||||
),
|
),
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate,
|
session.NewUserCheckedEvent(context.Background(), &session.NewAggregate("sessionID", "instanceID").Aggregate,
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
|
@ -166,8 +166,8 @@ func (s *SessionCommands) Exec(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SessionCommands) Start(ctx context.Context) {
|
func (s *SessionCommands) Start(ctx context.Context, userAgent *domain.UserAgent) {
|
||||||
s.eventCommands = append(s.eventCommands, session.NewAddedEvent(ctx, s.sessionWriteModel.aggregate))
|
s.eventCommands = append(s.eventCommands, session.NewAddedEvent(ctx, s.sessionWriteModel.aggregate, userAgent))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SessionCommands) UserChecked(ctx context.Context, userID string, checkedAt time.Time) error {
|
func (s *SessionCommands) UserChecked(ctx context.Context, userID string, checkedAt time.Time) error {
|
||||||
@ -280,7 +280,7 @@ func (s *SessionCommands) commands(ctx context.Context) (string, []eventstore.Co
|
|||||||
return token, s.eventCommands, nil
|
return token, s.eventCommands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, metadata map[string][]byte) (set *SessionChanged, err error) {
|
func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, metadata map[string][]byte, userAgent *domain.UserAgent) (set *SessionChanged, err error) {
|
||||||
sessionID, err := c.idGenerator.Next()
|
sessionID, err := c.idGenerator.Next()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -291,7 +291,7 @@ func (c *Commands) CreateSession(ctx context.Context, cmds []SessionCommand, met
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd := c.NewSessionCommands(cmds, sessionWriteModel)
|
cmd := c.NewSessionCommands(cmds, sessionWriteModel)
|
||||||
cmd.Start(ctx)
|
cmd.Start(ctx, userAgent)
|
||||||
return c.updateSession(ctx, cmd, metadata)
|
return c.updateSession(ctx, cmd, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,13 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -145,9 +148,10 @@ func TestCommands_CreateSession(t *testing.T) {
|
|||||||
tokenCreator func(sessionID string) (string, string, error)
|
tokenCreator func(sessionID string) (string, string, error)
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
checks []SessionCommand
|
checks []SessionCommand
|
||||||
metadata map[string][]byte
|
metadata map[string][]byte
|
||||||
|
userAgent *domain.UserAgent
|
||||||
}
|
}
|
||||||
type res struct {
|
type res struct {
|
||||||
want *SessionChanged
|
want *SessionChanged
|
||||||
@ -200,11 +204,25 @@ func TestCommands_CreateSession(t *testing.T) {
|
|||||||
},
|
},
|
||||||
args{
|
args{
|
||||||
ctx: authz.NewMockContext("", "org1", ""),
|
ctx: authz.NewMockContext("", "org1", ""),
|
||||||
|
userAgent: &domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[]expect{
|
[]expect{
|
||||||
expectFilter(),
|
expectFilter(),
|
||||||
expectPush(
|
expectPush(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
),
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID",
|
"tokenID",
|
||||||
),
|
),
|
||||||
@ -227,7 +245,7 @@ func TestCommands_CreateSession(t *testing.T) {
|
|||||||
idGenerator: tt.fields.idGenerator,
|
idGenerator: tt.fields.idGenerator,
|
||||||
sessionTokenCreator: tt.fields.tokenCreator,
|
sessionTokenCreator: tt.fields.tokenCreator,
|
||||||
}
|
}
|
||||||
got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.metadata)
|
got, err := c.CreateSession(tt.args.ctx, tt.args.checks, tt.args.metadata, tt.args.userAgent)
|
||||||
require.ErrorIs(t, err, tt.res.err)
|
require.ErrorIs(t, err, tt.res.err)
|
||||||
assert.Equal(t, tt.res.want, got)
|
assert.Equal(t, tt.res.want, got)
|
||||||
})
|
})
|
||||||
@ -276,7 +294,15 @@ func TestCommands_UpdateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID")),
|
"tokenID")),
|
||||||
@ -301,7 +327,15 @@ func TestCommands_UpdateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID")),
|
"tokenID")),
|
||||||
@ -866,7 +900,15 @@ func TestCommands_TerminateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID")),
|
"tokenID")),
|
||||||
@ -891,7 +933,15 @@ func TestCommands_TerminateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID")),
|
"tokenID")),
|
||||||
@ -920,7 +970,15 @@ func TestCommands_TerminateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID"),
|
"tokenID"),
|
||||||
@ -950,7 +1008,15 @@ func TestCommands_TerminateSession(t *testing.T) {
|
|||||||
eventstore: eventstoreExpect(t,
|
eventstore: eventstoreExpect(t,
|
||||||
expectFilter(
|
expectFilter(
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewAddedEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate)),
|
session.NewAddedEvent(context.Background(),
|
||||||
|
&session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
|
&domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fp1"),
|
||||||
|
IP: net.ParseIP("1.2.3.4"),
|
||||||
|
Description: gu.Ptr("firefox"),
|
||||||
|
Header: http.Header{"foo": []string{"bar"}},
|
||||||
|
},
|
||||||
|
)),
|
||||||
eventFromEventPusher(
|
eventFromEventPusher(
|
||||||
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
session.NewTokenSetEvent(context.Background(), &session.NewAggregate("sessionID", "org1").Aggregate,
|
||||||
"tokenID"),
|
"tokenID"),
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -147,7 +147,7 @@ func (c *HasherConfig) buildHasher() (hasher passwap.Hasher, prefixes []string,
|
|||||||
|
|
||||||
func (c *HasherConfig) decodeParams(dst any) error {
|
func (c *HasherConfig) decodeParams(dst any) error {
|
||||||
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||||
ErrorUnused: true,
|
ErrorUnused: false,
|
||||||
ErrorUnset: true,
|
ErrorUnset: true,
|
||||||
Result: dst,
|
Result: dst,
|
||||||
})
|
})
|
||||||
|
@ -379,7 +379,10 @@ func TestHasherConfig_decodeParams(t *testing.T) {
|
|||||||
"b": 2,
|
"b": 2,
|
||||||
"c": 3,
|
"c": 3,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
want: dst{
|
||||||
|
A: 1,
|
||||||
|
B: 2,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unset",
|
name: "unset",
|
||||||
|
17
internal/domain/user_agent.go
Normal file
17
internal/domain/user_agent.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
httplib "net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserAgent struct {
|
||||||
|
FingerprintID *string `json:"fingerprint_id,omitempty"`
|
||||||
|
IP net.IP `json:"ip,omitempty"`
|
||||||
|
Description *string `json:"description,omitempty"`
|
||||||
|
Header httplib.Header `json:"header,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ua UserAgent) IsEmpty() bool {
|
||||||
|
return ua.FingerprintID == nil && len(ua.IP) == 0 && ua.Description == nil && ua.Header == nil
|
||||||
|
}
|
@ -5,9 +5,9 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/crypto"
|
"github.com/go-jose/go-jose/v3"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/crypto"
|
||||||
"gopkg.in/square/go-jose.v2"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package azuread
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
||||||
|
@ -3,8 +3,8 @@ package azuread
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
httphelper "github.com/zitadel/oidc/v2/pkg/http"
|
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
"github.com/zitadel/zitadel/internal/idp/providers/oauth"
|
||||||
)
|
)
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package gitlab
|
package gitlab
|
||||||
|
|
||||||
import (
|
import (
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||||
|
@ -9,8 +9,8 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
"github.com/zitadel/zitadel/internal/idp/providers/oidc"
|
||||||
|
@ -9,8 +9,8 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
openid "github.com/zitadel/oidc/v2/pkg/oidc"
|
openid "github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -7,14 +7,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -3,8 +3,8 @@ package oauth
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
httphelper "github.com/zitadel/oidc/v2/pkg/http"
|
httphelper "github.com/zitadel/oidc/v3/pkg/http"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package oidc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
)
|
)
|
||||||
@ -100,7 +100,7 @@ func New(name, issuer, clientID, clientSecret, redirectURI string, scopes []stri
|
|||||||
for _, option := range options {
|
for _, option := range options {
|
||||||
option(provider)
|
option(provider)
|
||||||
}
|
}
|
||||||
provider.RelyingParty, err = rp.NewRelyingPartyOIDC(issuer, clientID, clientSecret, redirectURI, setDefaultScope(scopes), provider.options...)
|
provider.RelyingParty, err = rp.NewRelyingPartyOIDC(context.TODO(), issuer, clientID, clientSecret, redirectURI, setDefaultScope(scopes), provider.options...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import (
|
|||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/idp"
|
"github.com/zitadel/zitadel/internal/idp"
|
||||||
)
|
)
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
@ -38,7 +38,7 @@ func (s *Session) FetchUser(ctx context.Context) (user idp.User, err error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info, err := rp.Userinfo(
|
info, err := rp.Userinfo[*oidc.UserInfo](ctx,
|
||||||
s.Tokens.AccessToken,
|
s.Tokens.AccessToken,
|
||||||
s.Tokens.TokenType,
|
s.Tokens.TokenType,
|
||||||
s.Tokens.IDTokenClaims.GetSubject(),
|
s.Tokens.IDTokenClaims.GetSubject(),
|
||||||
|
@ -7,14 +7,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-jose/go-jose/v3"
|
||||||
"github.com/h2non/gock"
|
"github.com/h2non/gock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"gopkg.in/square/go-jose.v2"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
crewjam_saml "github.com/crewjam/saml"
|
crewjam_saml "github.com/crewjam/saml"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
@ -19,8 +19,8 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/zitadel/logging"
|
"github.com/zitadel/logging"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client"
|
"github.com/zitadel/oidc/v3/pkg/client"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
@ -8,10 +8,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/oidc/v2/pkg/client"
|
"github.com/zitadel/oidc/v3/pkg/client"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rp"
|
"github.com/zitadel/oidc/v3/pkg/client/rp"
|
||||||
"github.com/zitadel/oidc/v2/pkg/client/rs"
|
"github.com/zitadel/oidc/v3/pkg/client/rs"
|
||||||
"github.com/zitadel/oidc/v2/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
|
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
oidc_internal "github.com/zitadel/zitadel/internal/api/oidc"
|
oidc_internal "github.com/zitadel/zitadel/internal/api/oidc"
|
||||||
@ -83,8 +83,8 @@ func (s *Tester) CreateAPIClient(ctx context.Context, projectID string) (*manage
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) CreateOIDCAuthRequest(clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) {
|
func (s *Tester) CreateOIDCAuthRequest(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) {
|
||||||
provider, err := s.CreateRelyingParty(clientID, redirectURI, scope...)
|
provider, err := s.CreateRelyingParty(ctx, clientID, redirectURI, scope...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -110,8 +110,8 @@ func (s *Tester) CreateOIDCAuthRequest(clientID, loginClient, redirectURI string
|
|||||||
return strings.TrimPrefix(loc.String(), prefixWithHost), nil
|
return strings.TrimPrefix(loc.String(), prefixWithHost), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) CreateOIDCAuthRequestImplicit(clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) {
|
func (s *Tester) CreateOIDCAuthRequestImplicit(ctx context.Context, clientID, loginClient, redirectURI string, scope ...string) (authRequestID string, err error) {
|
||||||
provider, err := s.CreateRelyingParty(clientID, redirectURI, scope...)
|
provider, err := s.CreateRelyingParty(ctx, clientID, redirectURI, scope...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -146,12 +146,12 @@ func (s *Tester) OIDCIssuer() string {
|
|||||||
return http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure)
|
return http_util.BuildHTTP(s.Config.ExternalDomain, s.Config.Port, s.Config.ExternalSecure)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) CreateRelyingParty(clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) {
|
func (s *Tester) CreateRelyingParty(ctx context.Context, clientID, redirectURI string, scope ...string) (rp.RelyingParty, error) {
|
||||||
if len(scope) == 0 {
|
if len(scope) == 0 {
|
||||||
scope = []string{oidc.ScopeOpenID}
|
scope = []string{oidc.ScopeOpenID}
|
||||||
}
|
}
|
||||||
loginClient := &http.Client{Transport: &loginRoundTripper{http.DefaultTransport}}
|
loginClient := &http.Client{Transport: &loginRoundTripper{http.DefaultTransport}}
|
||||||
return rp.NewRelyingPartyOIDC(s.OIDCIssuer(), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient))
|
return rp.NewRelyingPartyOIDC(ctx, s.OIDCIssuer(), clientID, "", redirectURI, scope, rp.WithHTTPClient(loginClient))
|
||||||
}
|
}
|
||||||
|
|
||||||
type loginRoundTripper struct {
|
type loginRoundTripper struct {
|
||||||
@ -163,12 +163,12 @@ func (c *loginRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
|
|||||||
return c.RoundTripper.RoundTrip(req)
|
return c.RoundTripper.RoundTrip(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) CreateResourceServer(keyFileData []byte) (rs.ResourceServer, error) {
|
func (s *Tester) CreateResourceServer(ctx context.Context, keyFileData []byte) (rs.ResourceServer, error) {
|
||||||
keyFile, err := client.ConfigFromKeyFileData(keyFileData)
|
keyFile, err := client.ConfigFromKeyFileData(keyFileData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return rs.NewResourceServerJWTProfile(s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key))
|
return rs.NewResourceServerJWTProfile(ctx, s.OIDCIssuer(), keyFile.ClientID, keyFile.KeyID, []byte(keyFile.Key))
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRequest(url string, headers map[string]string) (*http.Request, error) {
|
func GetRequest(url string, headers map[string]string) (*http.Request, error) {
|
||||||
|
@ -17,8 +17,8 @@ var {{.ServiceName}}_AuthMethods = authz.MethodMapping {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{ range $m := .AuthContext}}
|
{{ range $m := .AuthContext}}
|
||||||
func (r *{{ $m.Name }}) OrganisationFromRequest() *middleware.Organisation {
|
func (r *{{ $m.Name }}) OrganizationFromRequest() *middleware.Organization {
|
||||||
return &middleware.Organisation{
|
return &middleware.Organization{
|
||||||
ID: r{{$m.OrgMethod}}.GetOrgId(),
|
ID: r{{$m.OrgMethod}}.GetOrgId(),
|
||||||
Domain: r{{$m.OrgMethod}}.GetOrgDomain(),
|
Domain: r{{$m.OrgMethod}}.GetOrgDomain(),
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ func assertPrepare(t *testing.T, prepareFunc, expectedObject interface{}, sqlExp
|
|||||||
}
|
}
|
||||||
return isErr(err)
|
return isErr(err)
|
||||||
}
|
}
|
||||||
object, ok, didScan := execScan(&database.DB{DB: client}, builder, scan, errCheck)
|
object, ok, didScan := execScan(t, &database.DB{DB: client}, builder, scan, errCheck)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Error(object)
|
t.Error(object)
|
||||||
return false
|
return false
|
||||||
@ -168,7 +168,7 @@ var (
|
|||||||
selectBuilderType = reflect.TypeOf(sq.SelectBuilder{})
|
selectBuilderType = reflect.TypeOf(sq.SelectBuilder{})
|
||||||
)
|
)
|
||||||
|
|
||||||
func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, errCheck checkErr) (object interface{}, ok bool, didScan bool) {
|
func execScan(t testing.TB, client *database.DB, builder sq.SelectBuilder, scan interface{}, errCheck checkErr) (object interface{}, ok bool, didScan bool) {
|
||||||
scanType := reflect.TypeOf(scan)
|
scanType := reflect.TypeOf(scan)
|
||||||
err := validateScan(scanType)
|
err := validateScan(scanType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -177,7 +177,7 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e
|
|||||||
|
|
||||||
stmt, args, err := builder.ToSql()
|
stmt, args, err := builder.ToSql()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unexpeted error from sql builder: %w", err), false, false
|
return fmt.Errorf("unexpected error from sql builder: %w", err), false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
//resultSet represents *sql.Row or *sql.Rows,
|
//resultSet represents *sql.Row or *sql.Rows,
|
||||||
@ -199,6 +199,9 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e
|
|||||||
// if scan(*sql.Row)...
|
// if scan(*sql.Row)...
|
||||||
} else if scanType.In(0).AssignableTo(rowType) {
|
} else if scanType.In(0).AssignableTo(rowType) {
|
||||||
err = client.QueryRow(func(r *sql.Row) error {
|
err = client.QueryRow(func(r *sql.Row) error {
|
||||||
|
if r.Err() != nil {
|
||||||
|
return r.Err()
|
||||||
|
}
|
||||||
didScan = true
|
didScan = true
|
||||||
res = reflect.ValueOf(scan).Call([]reflect.Value{reflect.ValueOf(r)})
|
res = reflect.ValueOf(scan).Call([]reflect.Value{reflect.ValueOf(r)})
|
||||||
if err, ok := res[1].Interface().(error); ok {
|
if err, ok := res[1].Interface().(error); ok {
|
||||||
@ -213,6 +216,9 @@ func execScan(client *database.DB, builder sq.SelectBuilder, scan interface{}, e
|
|||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err, ok := errCheck(err)
|
err, ok := errCheck(err)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
if didScan {
|
if didScan {
|
||||||
return res[0].Interface(), ok, didScan
|
return res[0].Interface(), ok, didScan
|
||||||
}
|
}
|
||||||
|
@ -14,27 +14,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SessionsProjectionTable = "projections.sessions5"
|
SessionsProjectionTable = "projections.sessions6"
|
||||||
|
|
||||||
SessionColumnID = "id"
|
SessionColumnID = "id"
|
||||||
SessionColumnCreationDate = "creation_date"
|
SessionColumnCreationDate = "creation_date"
|
||||||
SessionColumnChangeDate = "change_date"
|
SessionColumnChangeDate = "change_date"
|
||||||
SessionColumnSequence = "sequence"
|
SessionColumnSequence = "sequence"
|
||||||
SessionColumnState = "state"
|
SessionColumnState = "state"
|
||||||
SessionColumnResourceOwner = "resource_owner"
|
SessionColumnResourceOwner = "resource_owner"
|
||||||
SessionColumnInstanceID = "instance_id"
|
SessionColumnInstanceID = "instance_id"
|
||||||
SessionColumnCreator = "creator"
|
SessionColumnCreator = "creator"
|
||||||
SessionColumnUserID = "user_id"
|
SessionColumnUserID = "user_id"
|
||||||
SessionColumnUserCheckedAt = "user_checked_at"
|
SessionColumnUserCheckedAt = "user_checked_at"
|
||||||
SessionColumnPasswordCheckedAt = "password_checked_at"
|
SessionColumnPasswordCheckedAt = "password_checked_at"
|
||||||
SessionColumnIntentCheckedAt = "intent_checked_at"
|
SessionColumnIntentCheckedAt = "intent_checked_at"
|
||||||
SessionColumnWebAuthNCheckedAt = "webauthn_checked_at"
|
SessionColumnWebAuthNCheckedAt = "webauthn_checked_at"
|
||||||
SessionColumnWebAuthNUserVerified = "webauthn_user_verified"
|
SessionColumnWebAuthNUserVerified = "webauthn_user_verified"
|
||||||
SessionColumnTOTPCheckedAt = "totp_checked_at"
|
SessionColumnTOTPCheckedAt = "totp_checked_at"
|
||||||
SessionColumnOTPSMSCheckedAt = "otp_sms_checked_at"
|
SessionColumnOTPSMSCheckedAt = "otp_sms_checked_at"
|
||||||
SessionColumnOTPEmailCheckedAt = "otp_email_checked_at"
|
SessionColumnOTPEmailCheckedAt = "otp_email_checked_at"
|
||||||
SessionColumnMetadata = "metadata"
|
SessionColumnMetadata = "metadata"
|
||||||
SessionColumnTokenID = "token_id"
|
SessionColumnTokenID = "token_id"
|
||||||
|
SessionColumnUserAgentFingerprintID = "user_agent_fingerprint_id"
|
||||||
|
SessionColumnUserAgentIP = "user_agent_ip"
|
||||||
|
SessionColumnUserAgentDescription = "user_agent_description"
|
||||||
|
SessionColumnUserAgentHeader = "user_agent_header"
|
||||||
)
|
)
|
||||||
|
|
||||||
type sessionProjection struct{}
|
type sessionProjection struct{}
|
||||||
@ -69,8 +73,16 @@ func (*sessionProjection) Init() *old_handler.Check {
|
|||||||
handler.NewColumn(SessionColumnOTPEmailCheckedAt, handler.ColumnTypeTimestamp, handler.Nullable()),
|
handler.NewColumn(SessionColumnOTPEmailCheckedAt, handler.ColumnTypeTimestamp, handler.Nullable()),
|
||||||
handler.NewColumn(SessionColumnMetadata, handler.ColumnTypeJSONB, handler.Nullable()),
|
handler.NewColumn(SessionColumnMetadata, handler.ColumnTypeJSONB, handler.Nullable()),
|
||||||
handler.NewColumn(SessionColumnTokenID, handler.ColumnTypeText, handler.Nullable()),
|
handler.NewColumn(SessionColumnTokenID, handler.ColumnTypeText, handler.Nullable()),
|
||||||
|
handler.NewColumn(SessionColumnUserAgentFingerprintID, handler.ColumnTypeText, handler.Nullable()),
|
||||||
|
handler.NewColumn(SessionColumnUserAgentIP, handler.ColumnTypeText, handler.Nullable()),
|
||||||
|
handler.NewColumn(SessionColumnUserAgentDescription, handler.ColumnTypeText, handler.Nullable()),
|
||||||
|
handler.NewColumn(SessionColumnUserAgentHeader, handler.ColumnTypeJSONB, handler.Nullable()),
|
||||||
},
|
},
|
||||||
handler.NewPrimaryKey(SessionColumnInstanceID, SessionColumnID),
|
handler.NewPrimaryKey(SessionColumnInstanceID, SessionColumnID),
|
||||||
|
handler.WithIndex(handler.NewIndex(
|
||||||
|
SessionColumnUserAgentFingerprintID+"_idx",
|
||||||
|
[]string{SessionColumnUserAgentFingerprintID},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -153,19 +165,35 @@ func (p *sessionProjection) reduceSessionAdded(event eventstore.Event) (*handler
|
|||||||
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Sfrgf", "reduce.wrong.event.type %s", session.AddedType)
|
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Sfrgf", "reduce.wrong.event.type %s", session.AddedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
return handler.NewCreateStatement(
|
cols := make([]handler.Column, 0, 12)
|
||||||
e,
|
cols = append(cols,
|
||||||
[]handler.Column{
|
handler.NewCol(SessionColumnID, e.Aggregate().ID),
|
||||||
handler.NewCol(SessionColumnID, e.Aggregate().ID),
|
handler.NewCol(SessionColumnInstanceID, e.Aggregate().InstanceID),
|
||||||
handler.NewCol(SessionColumnInstanceID, e.Aggregate().InstanceID),
|
handler.NewCol(SessionColumnCreationDate, e.CreationDate()),
|
||||||
handler.NewCol(SessionColumnCreationDate, e.CreationDate()),
|
handler.NewCol(SessionColumnChangeDate, e.CreationDate()),
|
||||||
handler.NewCol(SessionColumnChangeDate, e.CreationDate()),
|
handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner),
|
||||||
handler.NewCol(SessionColumnResourceOwner, e.Aggregate().ResourceOwner),
|
handler.NewCol(SessionColumnState, domain.SessionStateActive),
|
||||||
handler.NewCol(SessionColumnState, domain.SessionStateActive),
|
handler.NewCol(SessionColumnSequence, e.Sequence()),
|
||||||
handler.NewCol(SessionColumnSequence, e.Sequence()),
|
handler.NewCol(SessionColumnCreator, e.User),
|
||||||
handler.NewCol(SessionColumnCreator, e.User),
|
)
|
||||||
},
|
if e.UserAgent != nil {
|
||||||
), nil
|
cols = append(cols,
|
||||||
|
handler.NewCol(SessionColumnUserAgentFingerprintID, e.UserAgent.FingerprintID),
|
||||||
|
handler.NewCol(SessionColumnUserAgentDescription, e.UserAgent.Description),
|
||||||
|
)
|
||||||
|
if e.UserAgent.IP != nil {
|
||||||
|
cols = append(cols,
|
||||||
|
handler.NewCol(SessionColumnUserAgentIP, e.UserAgent.IP.String()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if e.UserAgent.Header != nil {
|
||||||
|
cols = append(cols,
|
||||||
|
handler.NewJSONCol(SessionColumnUserAgentHeader, e.UserAgent.Header),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return handler.NewCreateStatement(e, cols), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *sessionProjection) reduceUserChecked(event eventstore.Event) (*handler.Statement, error) {
|
func (p *sessionProjection) reduceUserChecked(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/errors"
|
"github.com/zitadel/zitadel/internal/errors"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
@ -30,7 +32,15 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
session.AddedType,
|
session.AddedType,
|
||||||
session.AggregateType,
|
session.AggregateType,
|
||||||
[]byte(`{
|
[]byte(`{
|
||||||
"domain": "domain"
|
"domain": "domain",
|
||||||
|
"user_agent": {
|
||||||
|
"fingerprint_id": "fp1",
|
||||||
|
"ip": "1.2.3.4",
|
||||||
|
"description": "firefox",
|
||||||
|
"header": {
|
||||||
|
"foo": ["bar"]
|
||||||
|
}
|
||||||
|
}
|
||||||
}`),
|
}`),
|
||||||
), session.AddedEventMapper),
|
), session.AddedEventMapper),
|
||||||
},
|
},
|
||||||
@ -41,7 +51,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "INSERT INTO projections.sessions5 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
|
expectedStmt: "INSERT INTO projections.sessions6 (id, instance_id, creation_date, change_date, resource_owner, state, sequence, creator, user_agent_fingerprint_id, user_agent_description, user_agent_ip, user_agent_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -51,6 +61,10 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
domain.SessionStateActive,
|
domain.SessionStateActive,
|
||||||
uint64(15),
|
uint64(15),
|
||||||
"editor-user",
|
"editor-user",
|
||||||
|
gu.Ptr("fp1"),
|
||||||
|
gu.Ptr("firefox"),
|
||||||
|
"1.2.3.4",
|
||||||
|
[]byte(`{"foo":["bar"]}`),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -76,7 +90,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, user_id, user_checked_at) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -108,7 +122,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, password_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -140,7 +154,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, webauthn_checked_at, webauthn_user_verified) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, webauthn_checked_at, webauthn_user_verified) = ($1, $2, $3, $4) WHERE (id = $5) AND (instance_id = $6)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -172,7 +186,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, intent_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -203,7 +217,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, totp_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, totp_checked_at) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -234,7 +248,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, token_id) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -267,7 +281,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
expectedStmt: "UPDATE projections.sessions6 SET (change_date, sequence, metadata) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
anyArg{},
|
anyArg{},
|
||||||
anyArg{},
|
anyArg{},
|
||||||
@ -298,7 +312,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.sessions5 WHERE (id = $1) AND (instance_id = $2)",
|
expectedStmt: "DELETE FROM projections.sessions6 WHERE (id = $1) AND (instance_id = $2)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
"instance-id",
|
"instance-id",
|
||||||
@ -325,7 +339,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "DELETE FROM projections.sessions5 WHERE (instance_id = $1)",
|
expectedStmt: "DELETE FROM projections.sessions6 WHERE (instance_id = $1)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
"agg-id",
|
"agg-id",
|
||||||
},
|
},
|
||||||
@ -355,7 +369,7 @@ func TestSessionProjection_reduces(t *testing.T) {
|
|||||||
executer: &testExecuter{
|
executer: &testExecuter{
|
||||||
executions: []execution{
|
executions: []execution{
|
||||||
{
|
{
|
||||||
expectedStmt: "UPDATE projections.sessions5 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)",
|
expectedStmt: "UPDATE projections.sessions6 SET password_checked_at = $1 WHERE (user_id = $2) AND (password_checked_at < $3)",
|
||||||
expectedArgs: []interface{}{
|
expectedArgs: []interface{}{
|
||||||
nil,
|
nil,
|
||||||
"agg-id",
|
"agg-id",
|
||||||
|
@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
errs "errors"
|
errs "errors"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sq "github.com/Masterminds/squirrel"
|
sq "github.com/Masterminds/squirrel"
|
||||||
@ -41,6 +43,7 @@ type Session struct {
|
|||||||
OTPSMSFactor SessionOTPFactor
|
OTPSMSFactor SessionOTPFactor
|
||||||
OTPEmailFactor SessionOTPFactor
|
OTPEmailFactor SessionOTPFactor
|
||||||
Metadata map[string][]byte
|
Metadata map[string][]byte
|
||||||
|
UserAgent domain.UserAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
type SessionUserFactor struct {
|
type SessionUserFactor struct {
|
||||||
@ -166,6 +169,22 @@ var (
|
|||||||
name: projection.SessionColumnTokenID,
|
name: projection.SessionColumnTokenID,
|
||||||
table: sessionsTable,
|
table: sessionsTable,
|
||||||
}
|
}
|
||||||
|
SessionColumnUserAgentFingerprintID = Column{
|
||||||
|
name: projection.SessionColumnUserAgentFingerprintID,
|
||||||
|
table: sessionsTable,
|
||||||
|
}
|
||||||
|
SessionColumnUserAgentIP = Column{
|
||||||
|
name: projection.SessionColumnUserAgentIP,
|
||||||
|
table: sessionsTable,
|
||||||
|
}
|
||||||
|
SessionColumnUserAgentDescription = Column{
|
||||||
|
name: projection.SessionColumnUserAgentDescription,
|
||||||
|
table: sessionsTable,
|
||||||
|
}
|
||||||
|
SessionColumnUserAgentHeader = Column{
|
||||||
|
name: projection.SessionColumnUserAgentHeader,
|
||||||
|
table: sessionsTable,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (q *Queries) SessionByID(ctx context.Context, shouldTriggerBulk bool, id, sessionToken string) (session *Session, err error) {
|
func (q *Queries) SessionByID(ctx context.Context, shouldTriggerBulk bool, id, sessionToken string) (session *Session, err error) {
|
||||||
@ -265,6 +284,10 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
|||||||
SessionColumnOTPEmailCheckedAt.identifier(),
|
SessionColumnOTPEmailCheckedAt.identifier(),
|
||||||
SessionColumnMetadata.identifier(),
|
SessionColumnMetadata.identifier(),
|
||||||
SessionColumnToken.identifier(),
|
SessionColumnToken.identifier(),
|
||||||
|
SessionColumnUserAgentFingerprintID.identifier(),
|
||||||
|
SessionColumnUserAgentIP.identifier(),
|
||||||
|
SessionColumnUserAgentDescription.identifier(),
|
||||||
|
SessionColumnUserAgentHeader.identifier(),
|
||||||
).From(sessionsTable.identifier()).
|
).From(sessionsTable.identifier()).
|
||||||
LeftJoin(join(LoginNameUserIDCol, SessionColumnUserID)).
|
LeftJoin(join(LoginNameUserIDCol, SessionColumnUserID)).
|
||||||
LeftJoin(join(HumanUserIDCol, SessionColumnUserID)).
|
LeftJoin(join(HumanUserIDCol, SessionColumnUserID)).
|
||||||
@ -287,6 +310,8 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
|||||||
otpEmailCheckedAt sql.NullTime
|
otpEmailCheckedAt sql.NullTime
|
||||||
metadata database.Map[[]byte]
|
metadata database.Map[[]byte]
|
||||||
token sql.NullString
|
token sql.NullString
|
||||||
|
userAgentIP sql.NullString
|
||||||
|
userAgentHeader database.Map[[]string]
|
||||||
)
|
)
|
||||||
|
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
@ -311,6 +336,10 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
|||||||
&otpEmailCheckedAt,
|
&otpEmailCheckedAt,
|
||||||
&metadata,
|
&metadata,
|
||||||
&token,
|
&token,
|
||||||
|
&session.UserAgent.FingerprintID,
|
||||||
|
&userAgentIP,
|
||||||
|
&session.UserAgent.Description,
|
||||||
|
&userAgentHeader,
|
||||||
)
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -333,7 +362,11 @@ func prepareSessionQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuil
|
|||||||
session.OTPSMSFactor.OTPCheckedAt = otpSMSCheckedAt.Time
|
session.OTPSMSFactor.OTPCheckedAt = otpSMSCheckedAt.Time
|
||||||
session.OTPEmailFactor.OTPCheckedAt = otpEmailCheckedAt.Time
|
session.OTPEmailFactor.OTPCheckedAt = otpEmailCheckedAt.Time
|
||||||
session.Metadata = metadata
|
session.Metadata = metadata
|
||||||
|
session.UserAgent.Header = http.Header(userAgentHeader)
|
||||||
|
|
||||||
|
if userAgentIP.Valid {
|
||||||
|
session.UserAgent.IP = net.ParseIP(userAgentIP.String)
|
||||||
|
}
|
||||||
return session, token.String, nil
|
return session, token.String, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,13 @@ import (
|
|||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sq "github.com/Masterminds/squirrel"
|
sq "github.com/Masterminds/squirrel"
|
||||||
|
"github.com/muhlemmer/gu"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
@ -17,57 +20,61 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions5.id,` +
|
expectedSessionQuery = regexp.QuoteMeta(`SELECT projections.sessions6.id,` +
|
||||||
` projections.sessions5.creation_date,` +
|
` projections.sessions6.creation_date,` +
|
||||||
` projections.sessions5.change_date,` +
|
` projections.sessions6.change_date,` +
|
||||||
` projections.sessions5.sequence,` +
|
` projections.sessions6.sequence,` +
|
||||||
` projections.sessions5.state,` +
|
` projections.sessions6.state,` +
|
||||||
` projections.sessions5.resource_owner,` +
|
` projections.sessions6.resource_owner,` +
|
||||||
` projections.sessions5.creator,` +
|
` projections.sessions6.creator,` +
|
||||||
` projections.sessions5.user_id,` +
|
` projections.sessions6.user_id,` +
|
||||||
` projections.sessions5.user_checked_at,` +
|
` projections.sessions6.user_checked_at,` +
|
||||||
` projections.login_names2.login_name,` +
|
` projections.login_names2.login_name,` +
|
||||||
` projections.users8_humans.display_name,` +
|
` projections.users8_humans.display_name,` +
|
||||||
` projections.users8.resource_owner,` +
|
` projections.users8.resource_owner,` +
|
||||||
` projections.sessions5.password_checked_at,` +
|
` projections.sessions6.password_checked_at,` +
|
||||||
` projections.sessions5.intent_checked_at,` +
|
` projections.sessions6.intent_checked_at,` +
|
||||||
` projections.sessions5.webauthn_checked_at,` +
|
` projections.sessions6.webauthn_checked_at,` +
|
||||||
` projections.sessions5.webauthn_user_verified,` +
|
` projections.sessions6.webauthn_user_verified,` +
|
||||||
` projections.sessions5.totp_checked_at,` +
|
` projections.sessions6.totp_checked_at,` +
|
||||||
` projections.sessions5.otp_sms_checked_at,` +
|
` projections.sessions6.otp_sms_checked_at,` +
|
||||||
` projections.sessions5.otp_email_checked_at,` +
|
` projections.sessions6.otp_email_checked_at,` +
|
||||||
` projections.sessions5.metadata,` +
|
` projections.sessions6.metadata,` +
|
||||||
` projections.sessions5.token_id` +
|
` projections.sessions6.token_id,` +
|
||||||
` FROM projections.sessions5` +
|
` projections.sessions6.user_agent_fingerprint_id,` +
|
||||||
` LEFT JOIN projections.login_names2 ON projections.sessions5.user_id = projections.login_names2.user_id AND projections.sessions5.instance_id = projections.login_names2.instance_id` +
|
` projections.sessions6.user_agent_ip,` +
|
||||||
` LEFT JOIN projections.users8_humans ON projections.sessions5.user_id = projections.users8_humans.user_id AND projections.sessions5.instance_id = projections.users8_humans.instance_id` +
|
` projections.sessions6.user_agent_description,` +
|
||||||
` LEFT JOIN projections.users8 ON projections.sessions5.user_id = projections.users8.id AND projections.sessions5.instance_id = projections.users8.instance_id` +
|
` projections.sessions6.user_agent_header` +
|
||||||
|
` FROM projections.sessions6` +
|
||||||
|
` LEFT JOIN projections.login_names2 ON projections.sessions6.user_id = projections.login_names2.user_id AND projections.sessions6.instance_id = projections.login_names2.instance_id` +
|
||||||
|
` LEFT JOIN projections.users8_humans ON projections.sessions6.user_id = projections.users8_humans.user_id AND projections.sessions6.instance_id = projections.users8_humans.instance_id` +
|
||||||
|
` LEFT JOIN projections.users8 ON projections.sessions6.user_id = projections.users8.id AND projections.sessions6.instance_id = projections.users8.instance_id` +
|
||||||
` AS OF SYSTEM TIME '-1 ms'`)
|
` AS OF SYSTEM TIME '-1 ms'`)
|
||||||
expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions5.id,` +
|
expectedSessionsQuery = regexp.QuoteMeta(`SELECT projections.sessions6.id,` +
|
||||||
` projections.sessions5.creation_date,` +
|
` projections.sessions6.creation_date,` +
|
||||||
` projections.sessions5.change_date,` +
|
` projections.sessions6.change_date,` +
|
||||||
` projections.sessions5.sequence,` +
|
` projections.sessions6.sequence,` +
|
||||||
` projections.sessions5.state,` +
|
` projections.sessions6.state,` +
|
||||||
` projections.sessions5.resource_owner,` +
|
` projections.sessions6.resource_owner,` +
|
||||||
` projections.sessions5.creator,` +
|
` projections.sessions6.creator,` +
|
||||||
` projections.sessions5.user_id,` +
|
` projections.sessions6.user_id,` +
|
||||||
` projections.sessions5.user_checked_at,` +
|
` projections.sessions6.user_checked_at,` +
|
||||||
` projections.login_names2.login_name,` +
|
` projections.login_names2.login_name,` +
|
||||||
` projections.users8_humans.display_name,` +
|
` projections.users8_humans.display_name,` +
|
||||||
` projections.users8.resource_owner,` +
|
` projections.users8.resource_owner,` +
|
||||||
` projections.sessions5.password_checked_at,` +
|
` projections.sessions6.password_checked_at,` +
|
||||||
` projections.sessions5.intent_checked_at,` +
|
` projections.sessions6.intent_checked_at,` +
|
||||||
` projections.sessions5.webauthn_checked_at,` +
|
` projections.sessions6.webauthn_checked_at,` +
|
||||||
` projections.sessions5.webauthn_user_verified,` +
|
` projections.sessions6.webauthn_user_verified,` +
|
||||||
` projections.sessions5.totp_checked_at,` +
|
` projections.sessions6.totp_checked_at,` +
|
||||||
` projections.sessions5.otp_sms_checked_at,` +
|
` projections.sessions6.otp_sms_checked_at,` +
|
||||||
` projections.sessions5.otp_email_checked_at,` +
|
` projections.sessions6.otp_email_checked_at,` +
|
||||||
` projections.sessions5.metadata,` +
|
` projections.sessions6.metadata,` +
|
||||||
` COUNT(*) OVER ()` +
|
` COUNT(*) OVER ()` +
|
||||||
` FROM projections.sessions5` +
|
` FROM projections.sessions6` +
|
||||||
` LEFT JOIN projections.login_names2 ON projections.sessions5.user_id = projections.login_names2.user_id AND projections.sessions5.instance_id = projections.login_names2.instance_id` +
|
` LEFT JOIN projections.login_names2 ON projections.sessions6.user_id = projections.login_names2.user_id AND projections.sessions6.instance_id = projections.login_names2.instance_id` +
|
||||||
` LEFT JOIN projections.users8_humans ON projections.sessions5.user_id = projections.users8_humans.user_id AND projections.sessions5.instance_id = projections.users8_humans.instance_id` +
|
` LEFT JOIN projections.users8_humans ON projections.sessions6.user_id = projections.users8_humans.user_id AND projections.sessions6.instance_id = projections.users8_humans.instance_id` +
|
||||||
` LEFT JOIN projections.users8 ON projections.sessions5.user_id = projections.users8.id AND projections.sessions5.instance_id = projections.users8.instance_id` +
|
` LEFT JOIN projections.users8 ON projections.sessions6.user_id = projections.users8.id AND projections.sessions6.instance_id = projections.users8.instance_id` +
|
||||||
` AS OF SYSTEM TIME '-1 ms'`)
|
` AS OF SYSTEM TIME '-1 ms'`)
|
||||||
|
|
||||||
sessionCols = []string{
|
sessionCols = []string{
|
||||||
@ -92,6 +99,10 @@ var (
|
|||||||
"otp_email_checked_at",
|
"otp_email_checked_at",
|
||||||
"metadata",
|
"metadata",
|
||||||
"token",
|
"token",
|
||||||
|
"user_agent_fingerprint_id",
|
||||||
|
"user_agent_ip",
|
||||||
|
"user_agent_description",
|
||||||
|
"user_agent_header",
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionsCols = []string{
|
sessionsCols = []string{
|
||||||
@ -443,6 +454,10 @@ func Test_SessionPrepare(t *testing.T) {
|
|||||||
testNow,
|
testNow,
|
||||||
[]byte(`{"key": "dmFsdWU="}`),
|
[]byte(`{"key": "dmFsdWU="}`),
|
||||||
"tokenID",
|
"tokenID",
|
||||||
|
"fingerPrintID",
|
||||||
|
"1.2.3.4",
|
||||||
|
"agentDescription",
|
||||||
|
[]byte(`{"foo":["foo","bar"]}`),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -483,6 +498,12 @@ func Test_SessionPrepare(t *testing.T) {
|
|||||||
Metadata: map[string][]byte{
|
Metadata: map[string][]byte{
|
||||||
"key": []byte("value"),
|
"key": []byte("value"),
|
||||||
},
|
},
|
||||||
|
UserAgent: domain.UserAgent{
|
||||||
|
FingerprintID: gu.Ptr("fingerPrintID"),
|
||||||
|
IP: net.IPv4(1, 2, 3, 4),
|
||||||
|
Description: gu.Ptr("agentDescription"),
|
||||||
|
Header: http.Header{"foo": []string{"foo", "bar"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@ const (
|
|||||||
|
|
||||||
type AddedEvent struct {
|
type AddedEvent struct {
|
||||||
eventstore.BaseEvent `json:"-"`
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
UserAgent *domain.UserAgent `json:"user_agent,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *AddedEvent) Payload() interface{} {
|
func (e *AddedEvent) Payload() interface{} {
|
||||||
@ -45,6 +46,7 @@ func (e *AddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
|||||||
|
|
||||||
func NewAddedEvent(ctx context.Context,
|
func NewAddedEvent(ctx context.Context,
|
||||||
aggregate *eventstore.Aggregate,
|
aggregate *eventstore.Aggregate,
|
||||||
|
userAgent *domain.UserAgent,
|
||||||
) *AddedEvent {
|
) *AddedEvent {
|
||||||
return &AddedEvent{
|
return &AddedEvent{
|
||||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
@ -52,6 +54,7 @@ func NewAddedEvent(ctx context.Context,
|
|||||||
aggregate,
|
aggregate,
|
||||||
AddedType,
|
AddedType,
|
||||||
),
|
),
|
||||||
|
UserAgent: userAgent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go
Normal file
12
pkg/grpc/user/v2beta/user_service_org.pb.zitadel.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import "github.com/zitadel/zitadel/internal/api/grpc/server/middleware"
|
||||||
|
|
||||||
|
// OrganisationFromRequest implements deprecated [middleware.OrganisationFromRequest] interface.
|
||||||
|
// it will be removed before going GA (https://github.com/zitadel/zitadel/issues/6718)
|
||||||
|
func (r *AddHumanUserRequest) OrganisationFromRequest() *middleware.Organization {
|
||||||
|
return &middleware.Organization{
|
||||||
|
ID: r.GetOrganisation().GetOrgId(),
|
||||||
|
Domain: r.GetOrganisation().GetOrgDomain(),
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user