feat: add apple as idp (#6442)

* feat: manage apple idp

* handle apple idp callback

* add tests for provider

* basic console implementation

* implement flow for login UI and add logos / styling

* tests

* cleanup

* add upload button

* begin i18n

* apple logo positioning, file upload component

* fix add apple instance idp

* add missing apple logos for login

* update to go 1.21

* fix slice compare

* revert permission changes

* concrete error messages

* translate login apple logo -y-2px

* change form parsing

* sign in button

* fix tests

* lint console

---------

Co-authored-by: peintnermax <max@caos.ch>
This commit is contained in:
Livio Spring
2023-08-31 08:39:16 +02:00
committed by GitHub
parent 0d94947d3c
commit e17b49e4ca
89 changed files with 4384 additions and 64 deletions

View File

@@ -1648,6 +1648,42 @@ service AdminService {
};
}
// Add a new Apple identity provider on the instance
rpc AddAppleProvider(AddAppleProviderRequest) returns (AddAppleProviderResponse) {
option (google.api.http) = {
post: "/idps/apple"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "iam.idp.write"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Identity Providers";
summary: "Add Apple Identity Provider";
description: "";
};
}
// Change an existing Apple identity provider on the instance
rpc UpdateAppleProvider(UpdateAppleProviderRequest) returns (UpdateAppleProviderResponse) {
option (google.api.http) = {
put: "/idps/apple/{id}"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "iam.idp.write"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Identity Providers";
summary: "Update Apple Identity Provider";
description: "";
};
}
// Remove an identity provider
// Will remove all linked providers of this configuration on the users
rpc DeleteProvider(DeleteProviderRequest) returns (DeleteProviderResponse) {
@@ -5564,6 +5600,134 @@ message UpdateLDAPProviderResponse {
zitadel.v1.ObjectDetails details = 1;
}
message AddAppleProviderRequest {
// Apple will be used as default, if no name is provided
string name = 1 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200;
example: "\"Apple\"";
description: "Apple will be used as default, if no name is provided";
}
];
string client_id = 2 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"client-id\"";
description: "Client id (App ID or Service ID) provided by Apple";
}
];
string team_id = 3 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"ALT03JV3OS\"";
description: "(10-character) Team ID provided by Apple";
}
];
string key_id = 4 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"OGKDK25KD\"";
description: "(10-character) ID of the private key generated by Apple";
}
];
bytes private_key = 5 [
(validate.rules).bytes = {min_len: 1, max_len: 5000},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 5000;
example: "\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1...\"";
description: "Private Key generated by Apple";
}
];
repeated string scopes = 6 [
(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_items: 20,
example: "[\"name\", \"email\"]";
description: "The scopes requested by ZITADEL during the request to Apple";
}
];
zitadel.idp.v1.Options provider_options = 7;
}
message AddAppleProviderResponse {
zitadel.v1.ObjectDetails details = 1;
string id = 2;
}
message UpdateAppleProviderRequest {
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
string name = 2 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200,
example: "\"Apple\"";
}
];
string client_id = 3 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"client-id\"";
description: "Client id (App ID or Service ID) provided by Apple";
}
];
string team_id = 4 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"ALT03JV3OS\"";
description: "(10-character) Team ID provided by Apple";
}
];
string key_id = 5 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"OGKDK25KD\"";
description: "(10-character) ID of the private key generated by Apple";
}
];
bytes private_key = 6 [
(validate.rules).bytes = {max_len: 5000},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 5000,
example: "\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1...\"";
description: "Private Key generated by Apple";
}
];
repeated string scopes = 7 [
(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_items: 20,
example: "[\"openid\", \"profile\", \"email\"]";
description: "The scopes requested by ZITADEL during the request to Apple";
}
];
zitadel.idp.v1.Options provider_options = 8;
}
message UpdateAppleProviderResponse {
zitadel.v1.ObjectDetails details = 1;
}
message DeleteProviderRequest {
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
}

View File

@@ -266,6 +266,7 @@ enum ProviderType {
PROVIDER_TYPE_GITLAB = 8;
PROVIDER_TYPE_GITLAB_SELF_HOSTED = 9;
PROVIDER_TYPE_GOOGLE = 10;
PROVIDER_TYPE_APPLE = 11;
}
message ProviderConfig {
@@ -281,6 +282,7 @@ message ProviderConfig {
GitLabConfig gitlab = 9;
GitLabSelfHostedConfig gitlab_self_hosted = 10;
AzureADConfig azure_ad = 11;
AppleConfig apple = 12;
}
}
@@ -517,3 +519,30 @@ message AzureADTenant {
string tenant_id = 2;
}
}
message AppleConfig {
string client_id = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"com.client.id\"";
description: "Client id (App ID or Service ID) provided by Apple";
}
];
string team_id = 2 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"ALT03JV3OS\"";
description: "Team ID provided by Apple";
}
];
string key_id = 3 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"OGKDK25KD\"";
description: "ID of the private key generated by Apple";
}
];
repeated string scopes = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "[\"name\", \"email\"]";
description: "the scopes requested by ZITADEL during the request to Apple";
}
];
}

View File

@@ -7058,6 +7058,42 @@ service ManagementService {
};
}
// Add a new Apple identity provider in the organization
rpc AddAppleProvider(AddAppleProviderRequest) returns (AddAppleProviderResponse) {
option (google.api.http) = {
post: "/idps/apple"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Identity Providers";
summary: "Add Apple Identity Provider";
description: "";
};
}
// Change an existing Apple identity provider in the organization
rpc UpdateAppleProvider(UpdateAppleProviderRequest) returns (UpdateAppleProviderResponse) {
option (google.api.http) = {
put: "/idps/apple/{id}"
body: "*"
};
option (zitadel.v1.auth_option) = {
permission: "org.idp.write"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Identity Providers";
summary: "Update Apple Identity Provider";
description: "";
};
}
// Remove an identity provider
// Will remove all linked providers of this configuration on the users
rpc DeleteProvider(DeleteProviderRequest) returns (DeleteProviderResponse) {
@@ -12448,6 +12484,134 @@ message UpdateLDAPProviderResponse {
zitadel.v1.ObjectDetails details = 1;
}
message AddAppleProviderRequest {
// Apple will be used as default, if no name is provided
string name = 1 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200;
example: "\"Apple\"";
description: "Apple will be used as default, if no name is provided";
}
];
string client_id = 2 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"com.client.id\"";
description: "Client id (App ID or Service ID) provided by Apple";
}
];
string team_id = 3 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"ALT03JV3OS\"";
description: "(10-character) Team ID provided by Apple";
}
];
string key_id = 4 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"OGKDK25KD\"";
description: "(10-character) ID of the private key generated by Apple";
}
];
bytes private_key = 5 [
(validate.rules).bytes = {min_len: 1, max_len: 5000},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 5000;
example: "\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1...\"";
description: "Private Key generated by Apple";
}
];
repeated string scopes = 6 [
(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_items: 20,
example: "[\"name\", \"email\"]";
description: "The scopes requested by ZITADEL during the request to Apple";
}
];
zitadel.idp.v1.Options provider_options = 7;
}
message AddAppleProviderResponse {
zitadel.v1.ObjectDetails details = 1;
string id = 2;
}
message UpdateAppleProviderRequest {
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
string name = 2 [
(validate.rules).string = {max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200,
example: "\"Apple\"";
}
];
string client_id = 3 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200,
example: "\"client-id\"";
description: "Client id (App ID or Service ID) provided by Apple";
}
];
string team_id = 4 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"ALT03JV3OS\"";
description: "(10-character) Team ID provided by Apple";
}
];
string key_id = 5 [
(validate.rules).string = {len: 10},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 10;
max_length: 10;
example: "\"OGKDK25KD\"";
description: "(10-character) ID of the private key generated by Apple";
}
];
bytes private_key = 6 [
(validate.rules).bytes = {max_len: 5000},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 5000,
example: "\"LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1...\"";
description: "Private Key generated by Apple";
}
];
repeated string scopes = 7 [
(validate.rules).repeated = {max_items: 20, items: {string: {min_len: 1, max_len: 100}}},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_items: 20,
example: "[\"openid\", \"profile\", \"email\"]";
description: "The scopes requested by ZITADEL during the request to Apple";
}
];
zitadel.idp.v1.Options provider_options = 8;
}
message UpdateAppleProviderResponse {
zitadel.v1.ObjectDetails details = 1;
}
message DeleteProviderRequest {
string id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
}