mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 17:57:33 +00:00
feat(api): new session service (#5801)
* backup new protoc plugin * backup * session * backup * initial implementation * change to specific events * implement tests * cleanup * refactor: use new protoc plugin for api v2 * change package * simplify code * cleanup * cleanup * fix merge * start queries * fix tests * improve returned values * add token to projection * tests * test db map * update query * permission checks * fix tests and linting * rework token creation * i18n * refactor token check and fix tests * session to PB test * request to query tests * cleanup proto * test user check * add comment * simplify database map type * Update docs/docs/guides/integrate/access-zitadel-system-api.md Co-authored-by: Tim Möhlmann <tim+github@zitadel.com> * fix test * cleanup * docs --------- Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
This commit is contained in:
@@ -11,9 +11,35 @@ import "validate/validate.proto";
|
||||
message Organisation {
|
||||
oneof org {
|
||||
string org_id = 1;
|
||||
string org_domain = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ListQuery {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||
json_schema: {
|
||||
title: "General List Query"
|
||||
description: "Object unspecific list filters like offset, limit and asc/desc."
|
||||
}
|
||||
};
|
||||
uint64 offset = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"0\"";
|
||||
}
|
||||
];
|
||||
uint32 limit = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "100";
|
||||
description: "Maximum amount of events returned. The default is set to 1000 in https://github.com/zitadel/zitadel/blob/new-eventstore/cmd/zitadel/startup.yaml. If the limit exceeds the maximum configured ZITADEL will throw an error. If no limit is present the default is taken.";
|
||||
}
|
||||
];
|
||||
bool asc = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "default is descending"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message Details {
|
||||
//sequence represents the order of events. It's always counting
|
||||
//
|
||||
@@ -38,3 +64,21 @@ message Details {
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message ListDetails {
|
||||
uint64 total_result = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"2\"";
|
||||
}
|
||||
];
|
||||
uint64 processed_sequence = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"267831\"";
|
||||
}
|
||||
];
|
||||
google.protobuf.Timestamp timestamp = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "the last time the projection got updated"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@@ -2,11 +2,90 @@ syntax = "proto3";
|
||||
|
||||
package zitadel.session.v2alpha;
|
||||
|
||||
import "zitadel/user/v2alpha/user.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha;session";
|
||||
|
||||
message Session {
|
||||
string id = 1;
|
||||
zitadel.user.v2alpha.User user = 2;
|
||||
string id = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"id of the session\"";
|
||||
}
|
||||
];
|
||||
google.protobuf.Timestamp creation_date = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"time when the session was created\"";
|
||||
}
|
||||
];
|
||||
google.protobuf.Timestamp change_date = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"time when the session was last updated\"";
|
||||
}
|
||||
];
|
||||
uint64 sequence = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"sequence of the session\"";
|
||||
}
|
||||
];
|
||||
Factors factors = 5 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"checked factors of the session, e.g. the user, password and more\"";
|
||||
}
|
||||
];
|
||||
map<string, bytes> metadata = 6 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"custom key value list\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message Factors {
|
||||
UserFactor user = 1;
|
||||
PasswordFactor password = 2;
|
||||
}
|
||||
|
||||
message UserFactor {
|
||||
google.protobuf.Timestamp verified_at = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"time when the user was last checked\"";
|
||||
}
|
||||
];
|
||||
string id = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"id of the checked user\"";
|
||||
}
|
||||
];
|
||||
string login_name = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"login name of the checked user\"";
|
||||
}
|
||||
];
|
||||
string display_name = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"display name of the checked user\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message PasswordFactor {
|
||||
google.protobuf.Timestamp verified_at = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"time when the password was last checked\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SearchQuery {
|
||||
oneof query {
|
||||
option (validate.required) = true;
|
||||
|
||||
IDsQuery ids_query = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message IDsQuery {
|
||||
repeated string ids = 1;
|
||||
}
|
||||
|
@@ -3,21 +3,82 @@ syntax = "proto3";
|
||||
package zitadel.session.v2alpha;
|
||||
|
||||
|
||||
import "zitadel/object/v2alpha/object.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
import "zitadel/session/v2alpha/session.proto";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/session/v2alpha;session";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Session Service";
|
||||
version: "2.0-alpha";
|
||||
description: "This API is intended to manage sessions in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current login.";
|
||||
contact:{
|
||||
name: "ZITADEL"
|
||||
url: "https://zitadel.com"
|
||||
email: "hi@zitadel.com"
|
||||
}
|
||||
license: {
|
||||
name: "Apache 2.0",
|
||||
url: "https://github.com/zitadel/zitadel/blob/main/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTPS;
|
||||
schemes: HTTP;
|
||||
|
||||
consumes: "application/json";
|
||||
consumes: "application/grpc";
|
||||
|
||||
produces: "application/json";
|
||||
produces: "application/grpc";
|
||||
|
||||
consumes: "application/grpc-web+proto";
|
||||
produces: "application/grpc-web+proto";
|
||||
|
||||
host: "$ZITADEL_DOMAIN";
|
||||
base_path: "/";
|
||||
|
||||
external_docs: {
|
||||
description: "Detailed information about ZITADEL",
|
||||
url: "https://zitadel.com/docs"
|
||||
}
|
||||
|
||||
responses: {
|
||||
key: "403";
|
||||
value: {
|
||||
description: "Returned when the user does not have permission to access the resource.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "404";
|
||||
value: {
|
||||
description: "Returned when the resource does not exist.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
service SessionService {
|
||||
|
||||
// GetSession is to demonstrate an authenticated request, where the authenticated user (usage of another grpc package) is returned
|
||||
//
|
||||
// this request is subject to change and currently used for demonstration only
|
||||
rpc GetSession (GetSessionRequest) returns (GetSessionResponse) {
|
||||
// Search sessions
|
||||
rpc ListSessions (ListSessionsRequest) returns (ListSessionsResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v2alpha/sessions/{id}"
|
||||
post: "/v2alpha/sessions/_search"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
@@ -25,12 +86,280 @@ service SessionService {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Search sessions";
|
||||
description: "Search for sessions"
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
responses: {
|
||||
key: "400";
|
||||
value: {
|
||||
description: "invalid list query";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// GetSession a session
|
||||
rpc GetSession (GetSessionRequest) returns (GetSessionResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/v2alpha/sessions/{session_id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Get a session";
|
||||
description: "Get a session and all its information like the time of the user or password verification"
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Create a new session
|
||||
rpc CreateSession (CreateSessionRequest) returns (CreateSessionResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/v2alpha/sessions"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
http_response: {
|
||||
success_code: 201
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Create a new session";
|
||||
description: "Create a new session. A token will be returned, which is required for further updates of the session."
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Update a session
|
||||
rpc SetSession (SetSessionRequest) returns (SetSessionResponse) {
|
||||
option (google.api.http) = {
|
||||
patch: "/v2alpha/sessions/{session_id}"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Update an existing session";
|
||||
description: "Update an existing session with new information."
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Terminate a session
|
||||
rpc DeleteSession (DeleteSessionRequest) returns (DeleteSessionResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/v2alpha/sessions/{session_id}"
|
||||
body: "*"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Terminate an existing session";
|
||||
description: "Terminate your own session or if granted any other session."
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message ListSessionsRequest{
|
||||
zitadel.object.v2alpha.ListQuery query = 1;
|
||||
repeated SearchQuery queries = 2;
|
||||
}
|
||||
|
||||
message ListSessionsResponse{
|
||||
zitadel.object.v2alpha.ListDetails details = 1;
|
||||
repeated Session sessions = 2;
|
||||
}
|
||||
|
||||
message GetSessionRequest{
|
||||
string id = 1;
|
||||
string session_id = 1;
|
||||
optional string session_token = 2;
|
||||
}
|
||||
message GetSessionResponse{
|
||||
Session session = 1;
|
||||
}
|
||||
|
||||
message CreateSessionRequest{
|
||||
Checks checks = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"Check for user and password. Successful checks will be stated as factors on the session.\"";
|
||||
}
|
||||
];
|
||||
map<string, bytes> metadata = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"custom key value list to be stored on the session\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message CreateSessionResponse{
|
||||
zitadel.object.v2alpha.Details details = 1;
|
||||
string session_id = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"id of the session\"";
|
||||
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
||||
}
|
||||
];
|
||||
string session_token = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"token of the session, which is required for further updates of the session or the request other resources\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetSessionRequest{
|
||||
string session_id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
description: "\"id of the session to update\"";
|
||||
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
||||
}
|
||||
];
|
||||
string session_token = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
description: "\"token of the session, previously returned on the create / update request\"";
|
||||
}
|
||||
];
|
||||
Checks checks = 3[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"Check for user and password. Successful checks will be stated as factors on the session.\"";
|
||||
}
|
||||
];
|
||||
map<string, bytes> metadata = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"custom key value list to be stored on the session\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetSessionResponse{
|
||||
zitadel.object.v2alpha.Details details = 1;
|
||||
string session_token = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"token of the session, which is required for further updates of the session or the request other resources\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message DeleteSessionRequest{
|
||||
string session_id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
description: "\"id of the session to terminate\"";
|
||||
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
||||
}
|
||||
];
|
||||
optional string session_token = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"token of the session, previously returned on the create / update request\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message DeleteSessionResponse{
|
||||
zitadel.object.v2alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message Checks {
|
||||
optional CheckUser user = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"checks the user and updates the session on success\"";
|
||||
}
|
||||
];
|
||||
optional CheckPassword password = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "\"Checks the password and updates the session on success. Requires that the user is already checked, either in the previous or the same request.\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message CheckUser {
|
||||
oneof search {
|
||||
string user_id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
||||
}
|
||||
];
|
||||
string login_name = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
example: "\"mini@mouse.com\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
message CheckPassword {
|
||||
string password = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1;
|
||||
max_length: 200;
|
||||
example: "\"V3ryS3cure!\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
Reference in New Issue
Block a user