syntax = "proto3";

package com.wixpress.authorization.abac.management;

import "wix/api/validations.proto";
import "google/protobuf/wrappers.proto";
import "com/wixpress/authorization/abac/management/Subject.proto";

message PolicyCondition {
    // The type of the condition
    ConditionType condition = 1;
}

message ConditionType {
    oneof of {
        SimpleCondition simple_condition = 1[deprecated=true];
        // A logic combination between several conditions, with an operator between them
        JoinedCondition joined_conditions = 2;
        EnvironmentCondition environment_condition = 3[deprecated=true];
        // A single condition
        Condition condition = 4;
    }
}

message JoinedCondition {
    // The operator that should be used when evaluating the condition
    JoinedConditionOperator op = 1;
    // The conditions that should be evaluated, and then joined using the operator provided
    repeated ConditionType conditions = 2;
}

message Condition {
    // The unique identifier of the condition model. Indicates which actions the condition is working on
    string condition_model_id = 1;
    // The operator that should be evaluated
    ConditionOperator operator = 2;
}

message ConditionOperator {
    oneof operators {
        // Comparison of equality - will be evaluated to true if the given parties are equal
        EqualOperator equals = 1;
        // Regex operator - will be evaluated to true if the given value matches the provided regex
        LikeOperator like = 2;
        // Petri experiment - will be evaluated using petri.
        ExperimentOperator experiment = 3;
        // Operator that indicates a dependency on another subject being allowed to perform something.
        DependOnOperator depend_on = 4;
    }
}

message EqualOperator {
    // The attribute which should be compared. The attribute will be first evaluated to a value, and then compared the other side (attribute/value)
    string attr_name = 1;
    // The value to compare to. If the two parties are equal - we will return true.
    ConditionValue value = 2;
}

message LikeOperator {
    // The attribute which should be compared. The attribute will be first evaluated to a value, and then compared the regex values provided.
    string attr_name = 1;
    // The regex values which the attribute value should be evaluated on. If the attribute value matches at least one of the regular expressions provided - we will return true
    repeated string values = 2;
}

message ExperimentOperator {
    // The spec to conduct the experiment on.
    string spec = 1;
    // The value to use if the experiment could not be conducted
    string fallback_value = 2;
    // The expected value of the experiment conduction. If it matches the actual value - true will be returned. Otherwise - false.
    string expected_value = 3;
}

// Implies that the policy takes affect only if the depend on subject is permitted as well.
message DependOnOperator {
    // The subject on which the current entry depends on. If the subject is allowed to perform what the query was about - the condition will be evaluated to true. Otherwise - false
    Subject depend_on_subject = 1;
}

message SimpleCondition {
    string attr_name = 1;
    SimpleConditionValue value = 2;
    SimpleConditionOperator op = 3;
    string condition_model_id = 4;
}

message EnvironmentCondition {
    oneof condition {
        ExperimentCondition experiment_condition = 1;
    }
}

message SimpleConditionValue {
    oneof Value {
        string attr_name = 1;
        string string_value = 2;
        bool bool_value = 3;
    }
}

message ConditionValue {
    oneof Value {
        // an attribute. We'll first retrieve the value of the attribute (from the request or from pre-indexed values), and then compare to what it needs to be compared with.
        string attr_name = 1;
        // a value with a string type. Will be compared to the attribute provided, and be true only if they match the operator.
        string string_value = 2;
        // a value with a boolean type. Will be compared to the attribute provided, and be true only if they match the operator.
        bool bool_value = 3;
    }
}

message ExperimentCondition {
    string spec = 1;
    string fallback_value = 2;
    string expected_value = 3;
}

enum SimpleConditionOperator {
    UNKNOWN_SIMPLE_OP = 0;
    EQUAL = 1;
}

enum JoinedConditionOperator {
    UNKNOWN_JOIN_OP = 0;
    OR = 1;
    AND = 2;
}
