Skip to content

Commit

Permalink
Merge pull request #341 from TheThingsNetwork/feature/245-is-validations
Browse files Browse the repository at this point in the history
Identity Server (and some other) field validations
  • Loading branch information
htdvisser authored Mar 25, 2019
2 parents 9ba7761 + f21a060 commit c18583a
Show file tree
Hide file tree
Showing 39 changed files with 2,082 additions and 1,302 deletions.
10 changes: 5 additions & 5 deletions api/application.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ message Application {
google.protobuf.Timestamp created_at = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

string name = 4;
string description = 5;
map<string,string> attributes = 6;
string name = 4 [(validate.rules).string.max_len = 50];
string description = 5 [(validate.rules).string.max_len = 2000];
map<string,string> attributes = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
repeated ContactInfo contact_info = 7;
}

Expand Down Expand Up @@ -77,8 +77,8 @@ message UpdateApplicationRequest {

message CreateApplicationAPIKeyRequest {
ApplicationIdentifiers application_ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
string name = 2;
repeated Right rights = 3;
string name = 2 [(validate.rules).string.max_len = 50];
repeated Right rights = 3 [(validate.rules).repeated.items.enum.defined_only = true];;
}

message UpdateApplicationAPIKeyRequest {
Expand Down
2 changes: 1 addition & 1 deletion api/applicationserver_web.proto
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ message ApplicationWebhook {
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

// Base URL to which the message's path is appended.
string base_url = 4 [(gogoproto.customname) = "BaseURL"];
string base_url = 4 [(gogoproto.customname) = "BaseURL", (validate.rules).string.uri = true];
// HTTP headers to use.
map<string,string> headers = 5;
// The format to use for the body.
Expand Down
10 changes: 5 additions & 5 deletions api/client.proto
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ message Client {
google.protobuf.Timestamp created_at = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

string name = 4;
string description = 5;
map<string,string> attributes = 6;
string name = 4 [(validate.rules).string.max_len = 50];
string description = 5 [(validate.rules).string.max_len = 2000];
map<string,string> attributes = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
repeated ContactInfo contact_info = 7;

// The client secret is only visible to collaborators of the client.
Expand All @@ -67,11 +67,11 @@ message Client {
bool endorsed = 12;
// OAuth flows that can be used for the client to get a token.
// After a client is created, this field can only be modified by admins.
repeated GrantType grants = 13;
repeated GrantType grants = 13 [(validate.rules).repeated.items.enum.defined_only = true];
// Rights denotes what rights the client will have access to.
// Users that previously authorized this client will have to re-authorize the
// client after rights are added to this list.
repeated Right rights = 14;
repeated Right rights = 14 [(validate.rules).repeated.items.enum.defined_only = true];
}

message Clients {
Expand Down
22 changes: 11 additions & 11 deletions api/end_device.proto
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ message EndDeviceBrand {
}

message EndDeviceModel {
string brand_id = 1 [(gogoproto.customname) = "BrandID"];
string id = 2 [(gogoproto.customname) = "ID"];
string brand_id = 1 [(gogoproto.customname) = "BrandID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string id = 2 [(gogoproto.customname) = "ID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string name = 3;
}

// Identifies an end device model with version information.
message EndDeviceVersionIdentifiers {
string brand_id = 1 [(gogoproto.customname) = "BrandID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$", max_len: 36}];
string model_id = 2 [(gogoproto.customname) = "ModelID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$|^$", max_len: 36}];
string brand_id = 1 [(gogoproto.customname) = "BrandID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string model_id = 2 [(gogoproto.customname) = "ModelID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string hardware_version = 3;
string firmware_version = 4;
}
Expand All @@ -146,7 +146,7 @@ message EndDeviceVersion {
// LoRaWAN PHY version.
PHYVersion lorawan_phy_version = 3 [(gogoproto.customname) = "LoRaWANPHYVersion", (validate.rules).enum.defined_only = true];
// ID of the frequency plan used by this device.
string frequency_plan_id = 4 [(gogoproto.customname) = "FrequencyPlanID"];
string frequency_plan_id = 4 [(gogoproto.customname) = "FrequencyPlanID", (validate.rules).string.max_len = 64];

// Photos contains file names of device photos.
repeated string photos = 5;
Expand Down Expand Up @@ -326,17 +326,17 @@ message EndDevice {
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

// Friendly name of the device. Stored in Entity Registry.
string name = 4;
string name = 4 [(validate.rules).string.max_len = 50];
// Description of the device. Stored in Entity Registry.
string description = 5;
string description = 5 [(validate.rules).string.max_len = 2000];
// Attributes of the device. Stored in Entity Registry.
map<string,string> attributes = 6;
map<string,string> attributes = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];

// Version Identifiers. Stored in Entity Registry, Network Server and Application Server.
EndDeviceVersionIdentifiers version_ids = 7 [(gogoproto.customname) = "VersionIDs"];

// Default service profile. Stored in Entity Registry.
string service_profile_id = 8 [(gogoproto.customname) = "ServiceProfileID"];
string service_profile_id = 8 [(gogoproto.customname) = "ServiceProfileID", (validate.rules).string.max_len = 64];

// The address of the Network Server where this device is supposed to be registered.
// Stored in Entity Registry and Join Server.
Expand All @@ -361,7 +361,7 @@ message EndDevice {
string join_server_address = 11 [(validate.rules).string.pattern = "^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])(?::[0-9]{1,5})?$|^$"];

// Location of the device. Stored in Entity Registry.
map<string,Location> locations = 12;
map<string,Location> locations = 12 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];

// Whether the device supports class B.
// Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any.
Expand All @@ -377,7 +377,7 @@ message EndDevice {
PHYVersion lorawan_phy_version = 16 [(gogoproto.customname) = "LoRaWANPHYVersion", (validate.rules).enum.defined_only = true];
// ID of the frequency plan used by this device.
// Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any.
string frequency_plan_id = 17 [(gogoproto.customname) = "FrequencyPlanID"];
string frequency_plan_id = 17 [(gogoproto.customname) = "FrequencyPlanID", (validate.rules).string.max_len = 64];
// Minimum frequency the device is capable of using (Hz). Stored in Network Server.
// Copied on creation from template identified by version_ids, if any or from the home Network Server device profile, if any.
uint64 min_frequency = 18;
Expand Down
26 changes: 13 additions & 13 deletions api/gateway.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ message GatewayBrand {
}

message GatewayModel {
string brand_id = 1 [(gogoproto.customname) = "BrandID"];
string id = 2 [(gogoproto.customname) = "ID"];
string brand_id = 1 [(gogoproto.customname) = "BrandID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string id = 2 [(gogoproto.customname) = "ID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string name = 3;
}

// Identifies an end device model with version information.
message GatewayVersionIdentifiers {
string brand_id = 1 [(gogoproto.customname) = "BrandID"];
string model_id = 2 [(gogoproto.customname) = "ModelID"];
string brand_id = 1 [(gogoproto.customname) = "BrandID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string model_id = 2 [(gogoproto.customname) = "ModelID", (validate.rules).string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$", max_len: 36}];
string hardware_version = 3;
string firmware_version = 4;
}
Expand Down Expand Up @@ -84,9 +84,9 @@ message Gateway {
google.protobuf.Timestamp created_at = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

string name = 4;
string description = 5;
map<string,string> attributes = 6;
string name = 4 [(validate.rules).string.max_len = 50];
string description = 5 [(validate.rules).string.max_len = 2000];
map<string,string> attributes = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
repeated ContactInfo contact_info = 7;

GatewayVersionIdentifiers version_ids = 8 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
Expand All @@ -99,7 +99,7 @@ message Gateway {
string gateway_server_address = 9 [(validate.rules).string.pattern = "^(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*(?:[A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])(?::[0-9]{1,5})?$|^$"];
bool auto_update = 10;
string update_channel = 11;
string frequency_plan_id = 12 [(gogoproto.customname) = "FrequencyPlanID"];
string frequency_plan_id = 12 [(gogoproto.customname) = "FrequencyPlanID", (validate.rules).string.max_len = 64];
repeated GatewayAntenna antennas = 13 [(gogoproto.nullable) = false];
// The status of this gateway may be publicly displayed.
bool status_public = 14;
Expand Down Expand Up @@ -158,8 +158,8 @@ message UpdateGatewayRequest {

message CreateGatewayAPIKeyRequest {
GatewayIdentifiers gateway_ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
string name = 2;
repeated Right rights = 3;
string name = 2 [(validate.rules).string.max_len = 50];
repeated Right rights = 3 [(validate.rules).repeated.items.enum.defined_only = true];
}

message UpdateGatewayAPIKeyRequest {
Expand All @@ -178,7 +178,7 @@ message GatewayAntenna {
float gain = 1;
// location is the antenna's location.
Location location = 2 [(gogoproto.nullable) = false, (validate.rules).message.required = true];
map<string,string> attributes = 3;
map<string,string> attributes = 3 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
}

message GatewayStatus {
Expand All @@ -196,7 +196,7 @@ message GatewayStatus {
// fpga: "48"
// dsp: "27"
// hal: "v2-3.5.0"
map<string,string> versions = 3;
map<string,string> versions = 3 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
// Location of each gateway's antenna
// - if left out, server uses registry-set location as fallback
repeated Location antenna_locations = 4;
Expand All @@ -206,7 +206,7 @@ message GatewayStatus {
// Metrics
// - can be used for forwarding gateway metrics such as temperatures or performance metrics
// - map keys are written in snake_case
map<string,float> metrics = 6;
map<string,float> metrics = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
// Advanced metadata fields
// - can be used for advanced information or experimental features that are not yet formally defined in the API
// - field names are written in snake_case
Expand Down
2 changes: 1 addition & 1 deletion api/joinserver.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ option go_package = "go.thethings.network/lorawan-stack/pkg/ttnpb";

message SessionKeyRequest {
// Join Server issued identifier for the session keys.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID"];
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
// LoRaWAN DevEUI.
bytes dev_eui = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "go.thethings.network/lorawan-stack/pkg/types.EUI64", (gogoproto.customname) = "DevEUI"];
}
Expand Down
5 changes: 3 additions & 2 deletions api/keys.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
syntax = "proto3";

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "github.com/lyft/protoc-gen-validate/validate/validate.proto";

package ttn.lorawan.v3;

Expand All @@ -31,7 +32,7 @@ message KeyEnvelope {
// These are stored on the Join Server.
message RootKeys {
// Join Server issued identifier for the root keys.
string root_key_id = 1 [(gogoproto.customname) = "RootKeyID"];
string root_key_id = 1 [(gogoproto.customname) = "RootKeyID", (validate.rules).string.max_len = 2048];
// The (encrypted) Application Key.
KeyEnvelope app_key = 2;
// The (encrypted) Network Key.
Expand All @@ -45,7 +46,7 @@ message SessionKeys {

// Join Server issued identifier for the session keys.
// This ID can be used to request the keys from the Join Server in case the are lost.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID"];
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
// The (encrypted) Forwarding Network Session Integrity Key (or Network Session Key in 1.0 compatibility mode).
// This key is stored by the (forwarding) Network Server.
KeyEnvelope f_nwk_s_int_key = 2;
Expand Down
8 changes: 4 additions & 4 deletions api/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ message TxAcknowledgment {

message ApplicationUplink {
// Join Server issued identifier for the session keys used by this uplink.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID"];
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
uint32 f_port = 2 [(validate.rules).uint32.lte = 255];
uint32 f_cnt = 3;
bytes frm_payload = 4 [(gogoproto.customname) = "FRMPayload"];
Expand All @@ -167,12 +167,12 @@ message ApplicationUplink {
message ApplicationLocation {
string service = 1;
Location location = 2 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
map<string,string> attributes = 3;
map<string,string> attributes = 3 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
}

message ApplicationJoinAccept {
// Join Server issued identifier for the session keys negotiated in this join.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID"];
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
// Encrypted Application Session Key (if Join Server sent it to Network Server).
KeyEnvelope app_s_key = 2;
// Downlink messages in the queue that got invalidated because of the session change.
Expand All @@ -186,7 +186,7 @@ message ApplicationDownlink {
option (gogoproto.populate) = false;

// Join Server issued identifier for the session keys used by this downlink.
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID"];
bytes session_key_id = 1 [(gogoproto.customname) = "SessionKeyID", (validate.rules).bytes.max_len = 2048];
uint32 f_port = 2 [(validate.rules).uint32.lte = 255];
uint32 f_cnt = 3;
bytes frm_payload = 4 [(gogoproto.customname) = "FRMPayload"];
Expand Down
2 changes: 1 addition & 1 deletion api/oauth.proto
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ message OAuthAuthorizationCode {
ClientIdentifiers client_ids = 2 [(gogoproto.customname) = "ClientIDs", (gogoproto.nullable) = false, (validate.rules).message.required = true];
repeated Right rights = 3;
string code = 4;
string redirect_uri = 5 [(gogoproto.customname) = "RedirectURI"];
string redirect_uri = 5 [(gogoproto.customname) = "RedirectURI", (validate.rules).string.uri_ref = true];
string state = 6;
google.protobuf.Timestamp created_at = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp expires_at = 8 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
Expand Down
10 changes: 5 additions & 5 deletions api/organization.proto
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ message Organization {
google.protobuf.Timestamp created_at = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp updated_at = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

string name = 4;
string description = 5;
map<string,string> attributes = 6;
string name = 4 [(validate.rules).string.max_len = 50];
string description = 5 [(validate.rules).string.max_len = 2000];
map<string,string> attributes = 6 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];
repeated ContactInfo contact_info = 7;
}

Expand Down Expand Up @@ -79,8 +79,8 @@ message UpdateOrganizationRequest {

message CreateOrganizationAPIKeyRequest {
OrganizationIdentifiers organization_ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
string name = 2;
repeated Right rights = 3;
string name = 2 [(validate.rules).string.max_len = 50];
repeated Right rights = 3 [(validate.rules).repeated.items.enum.defined_only = true];
}

message UpdateOrganizationAPIKeyRequest {
Expand Down
8 changes: 4 additions & 4 deletions api/rights.proto
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ enum Right {
}

message Rights {
repeated Right rights = 1;
repeated Right rights = 1 [(validate.rules).repeated.items.enum.defined_only = true];
}

message APIKey {
Expand All @@ -165,10 +165,10 @@ message APIKey {
string key = 2;

// User-defined (friendly) name for the API key.
string name = 3;
string name = 3 [(validate.rules).string.max_len = 50];

// Rights that are granted to this API key.
repeated Right rights = 4;
repeated Right rights = 4 [(validate.rules).repeated.items.enum.defined_only = true];
}

message APIKeys {
Expand All @@ -177,7 +177,7 @@ message APIKeys {

message Collaborator {
OrganizationOrUserIdentifiers ids = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false, (validate.rules).message.required = true];
repeated Right rights = 2;
repeated Right rights = 2 [(validate.rules).repeated.items.enum.defined_only = true];
}

message Collaborators {
Expand Down
4 changes: 2 additions & 2 deletions api/search_services.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ message SearchEntitiesRequest {
// Find entities where the description contains this substring.
string description_contains = 3;
// Find entities where the given attributes contain these substrings.
map<string,string> attributes_contain = 4;
map<string,string> attributes_contain = 4 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];

reserved 5; // TODO: Add filter for approval state (admin only).

Expand Down Expand Up @@ -91,7 +91,7 @@ message SearchEndDevicesRequest {
// Find end devices where the description contains this substring.
string description_contains = 4;
// Find end devices where the given attributes contain these substrings.
map<string,string> attributes_contain = 5;
map<string,string> attributes_contain = 5 [(validate.rules).map.keys.string = {pattern: "^[a-z0-9](?:[-]?[a-z0-9]){2,}$" , max_len: 36}];

// Find end devices where the (hexadecimal) DevEUI contains this substring.
string dev_eui_contains = 6 [(gogoproto.customname) = "DevEUIContains"];
Expand Down
Loading

0 comments on commit c18583a

Please sign in to comment.