// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
syntax = "proto2";
package kudu.security;

option java_package = "org.apache.kudu.security";

import "kudu/util/pb_util.proto";

message ColumnPrivilegePB {
  // If set, the user has privileges to select and apply predicates on the
  // column during scans.
  optional bool scan_privilege = 1;
};

message TablePrivilegePB {
  // The ID of the table to which the privileges apply.
  optional string table_id = 1;

  // If set, the user is authorized to select and apply predicates to all
  // columns when scanning the table, and `column_privileges` is ignored. If
  // unset, the user may only scan and apply predicates to columns with the
  // privileges specified in `column_privileges`.
  optional bool scan_privilege = 2;

  // If set, the user is authorized to insert rows into the table.
  optional bool insert_privilege= 3;

  // If set, the user is authorized to update rows in the table.
  optional bool update_privilege = 4;

  // If set, the user is authorized to delete rows in the table.
  optional bool delete_privilege = 5;

  // Per-column privileges, indexed by column ID.
  map<int32, ColumnPrivilegePB> column_privileges = 6;
};

message AuthnTokenPB {
  optional string username = 1;
};

message AuthzTokenPB {
  optional string username = 1;
  optional TablePrivilegePB table_privilege = 2;
};

message TokenPB {
  // The time at which this token expires, in seconds since the
  // unix epoch.
  optional int64 expire_unix_epoch_seconds = 1;

  enum Feature {
    // Protobuf doesn't let us define a enum with no values,
    // so we've got this placeholder in here for now. When we add
    // the first real feature flag, we can remove this.
    UNUSED_PLACEHOLDER = 999;
  };

  // List of incompatible features used by this token. If a feature
  // is listed in the token and a server verifying/authorizing the token
  // sees an UNKNOWN value in this list, it should reject the token.
  //
  // This allows us to safely add "restrictive" content to tokens
  // and have a "default deny" policy on servers that may not understand
  // them.
  //
  // We use an int32 here but the values correspond to the 'Feature' enum
  // above. This is to deal with protobuf's odd handling of unknown enum
  // values (see KUDU-1850).
  repeated int32 incompatible_features = 2;

  oneof token {
    AuthnTokenPB authn = 3;
    AuthzTokenPB authz = 4;
  }
};

message SignedTokenPB {
  // The actual token data. This is a serialized TokenPB protobuf. However, we use a
  // 'bytes' field, since protobuf doesn't guarantee that if two implementations serialize
  // a protobuf, they'll necessary get bytewise identical results, particularly in the
  // presence of unknown fields.
  optional bytes token_data = 1;

  // The cryptographic signature of 'token_contents'.
  optional bytes signature = 2 [ (kudu.REDACT) = true ];

  // The sequence number of the key which produced 'signature'.
  optional int64 signing_key_seq_num = 3;
};

// A private key used to sign tokens.
message TokenSigningPrivateKeyPB {
  optional int64 key_seq_num = 1;

  // The private key material, in DER format.
  optional bytes rsa_key_der = 2 [ (kudu.REDACT) = true ];

  // The time at which signatures made by this key should no longer be valid.
  optional int64 expire_unix_epoch_seconds = 3;
};

// A public key corresponding to the private key used to sign tokens. Only
// this part is necessary for token verification.
message TokenSigningPublicKeyPB {
  optional int64 key_seq_num = 1;

  // The public key material, in DER format.
  optional bytes rsa_key_der = 2;

  // The time at which signatures made by this key should no longer be valid.
  optional int64 expire_unix_epoch_seconds = 3;
};
