Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagejava
public enum ScramMechanismType {
    UNKNOWN(0),
    HMAC_SHA_256(1),
    HMAC_SHA_512(2);

    byte type;

    private ScramMechanismType(byte type) {
        this.type = type;
    }
}

public class ScramMechanism {
    private final ScramMechanismType type;
    private final int iterations;
    private final String password; // will be null when listing

    public static ScramMechanism parse(String str);

    public ScramMechanism(ScramMechanismType type, int iterations, String password) {
        this.type = type;
        this.iterations = iterations);
        this.password = password;
    }

    public ScramMechanismType type() {
        return type;
    }

    public int iterations() {
        return iterations;
    }
}

public class ScramUser {
 public String password() {
        return password;
    }
}

public class ScramUserListing {
    private final String name;
    private final ScramMechanismList<ScramMechanism> mechanism;

    public ScramUserScramUserListing(String name, ScramMechanismList<ScramMechanism> mechanism) {
        this.name = name;
        this.mechanism = mechanism;
    }

    public String name() {
        return name;
    }

    public ScramMechanismList<ScramMechanism> mechanism() {
        return mechanism;
    }
}

public class ListScramUsersOptions extends AbstractOptions<ListScramUsersOptions> { }

default ListScramUsersResult listScramUsers() {
    return listScramUsers(new ListScramUsersOptions());
}

ListScramUsersResult listScramUsers(ListScramUsersOptions options);

public class ListScramUsersResult {
    public KafkaFuture<Map<String, ScramUser>> all();
}

...

Code Block
{ 
  "apiKey": 50,
  "type": "request",
  "name": "ListScramUsersRequest",
  "validVersions": "0",
  "flexibleVersions": "0+",
  "fields": [
  ]
}

{ 
  "apiKey": 50, 
  "type": "response",
  "name": "ListScramUsersResponse", 
  "validVersions": "0", 
  "flexibleVersions": "0+", 
  "fields": [ 
    { "name": "Error", "type": "int16", "versions": "0+",
      "about": "The message-level error code." },
    { "name": "ErrorMessage", "type": "string", "versions": "0+", "nullableVersions": "0+",
      "about": "The message-level error message." },
    { "name": "Users", "type": "[]ScramUser", "versions": "0+",
      "about": "The SCRAM users.", "fields": [
        { "name": "Name", "type": "string", "versions": "0+",
          "about": "The user name." },
        { "name": "MechanismTypeMechanisms", "type": "int8ScramUserMechanism", "versions": "0+",
          "about": "The SCRAMuser mechanism typename." },
        { "name": "MechanismIterationsType", "type": "int32int8", "versions": "0+",
          "about": "The number of iterations used in the SCRAM mechanism type." },
    ]}
  ]
}

    { "name": "Iterations", "type": "int32", "versions": "0+",
          "about": "The number of iterations used in the SCRAM mechanism." }
      }
    ]}
  ]
}

It will require ALTER permissions on the It will require ALTER permissions on the CLUSTER resource.  It will return CLUSTER_AUTHORIZATION_FAILED if the user has insufficient permissions.

...

Code Block
public class ScramUserDeletion {
    private final String user;

    ScramUserDeletion(String user) {
        this.user = user;
    }

    public String user() {
        return user;
    }
}

public class ScramUserAlteration {
    private final ScramUserString user;
    private final StringList<ScramMechanism> password;

    public ScramCredentialAlteration(ScramUserString user, StringList<ScramMechanism> passwordmechanisms) {
        this.user = user;
        this.passwordmechanisms = passwordmechanisms;
    }

    public ScramUserString user() {
        return user;
    }

    public StringList<ScramMechanism> passwordmechanisms() {
        return passwordmechanisms;
    }
}

public class AlterScramUsersOptions extends AbstractOptions<AlterScramUsersOptions> {}

default AlterScramUsersResult alterScramUsers(List<ScramUserDeletion> deletions,
                                              List<ScramUserAlteration> alterations) {
    return alterScramUsers(deletions, alterations, new AlterScramUsersOptions());
}

AlterScramUsersResult alterScramUsers(List<ScramUserDeletion> deletions,


AlterScramUsersResult alterScramUsers(List<ScramUserDeletion> deletions,
                                      List<ScramUserAlteration> alterations,
                          List<ScramUserAlteration> alterations,
           AlterScramUsersOptions options);

public class AlterScramCredentialsResult {
    public KafkaFuture<Void> all();
    public Map<String, KafkaFuture<Void>> results();
}

The AlterScramUsersRequest and AlterScreamUsersResponse implement the new API.

Code Block
languagejava
{ 
  "apiKey": 51, 
      AlterScramUsersOptions options);

public class AlterScramCredentialsResult {
    public KafkaFuture<Void> all();
    public Map<String, KafkaFuture<Void>> results();
}

The AlterScramUsersRequest and AlterScreamUsersResponse implement the new API.

Code Block
languagejava
{ 
  "apiKey": 51, 
  "type": "response",
  "name": "AlterScramUsersRequest",
  "validVersions": "0", 
  "flexibleVersions": "0+", 
  "type": "response",
  "name": "AlterScramUsersRequest",
  "validVersions": "0", 
  "flexibleVersions": "0+", 
  "fields": [ 
    { "name": "Deletions", "type": "[]ScramUserDeletion", "versions": "0+",
      "about": "The SCRAM users to remove.", "fields": [
    
    { "name": "DeletionsName", "type": "[]ScramUserDeletionstring", "versions": "0+",
      "about": "The SCRAM users to remove.", "fields": ["about": "The user name." }
      ]},
    { "name": "NameAlterations", "type": "string[]ScramUserAlteration", "versions": "0+",
          "about": "The SCRAM userusers to namealter.", "fields": }[
      ]},
    { "name": "AlterationsName", "type": "[]ScramUserAlterationstring", "versions": "0+",
        "about": "The SCRAM users to alteruser name.", "fields": [
   }
      { "name": "NameMechanisms", "type": "stringScramMechanism", "versions": "0+",
          "about": "The user nameSCRAM mechanisms to configure." }
        { "name": "MechanismTypeType", "type": "int8", "versions": "0+",
          "about": "The mechanism type." },
        { "name": "MechanismIterationsIterations", "type": "int32", "versions": "0+",
          "about": "The number of iterations, or -1 to use the server default." },
        { "name": "Password", "type": "string", "versions": "0+", ",
          "about": "The password." }
      ]}
    ]}  
  ]       
}   

{ 
  "apiKey": 51, 
  "type": "response",
  "name": "AlterScramUsersResponse",
  "validVersions": "0", 
  "flexibleVersions": "0+", 
  "fields": [ 
    { "name": "Results", "type": "[]AlterScramUsersResult", "versions": "0+",
      "about": "The results for removals, followed by the results for alterations.", "fields": [
        { "name": "ErrorCode", "type": "int8", "versions": "0+",
          "about": "The error code." },
        { "name": "ErrorString", "type": "string", "versions": "0+", "nullableVersions": "0+",
          "about": "The error message, if any." }
    ]}  
  ]       
}   

...

Rather than creating new RPCs, we could have extended the IncrementalAlterConfigs RPC to support changing SCRAM configurations.  However, this would involve some fairly complex string manipulation for clients that wanted to use the API.  It would also be more cumbersome to report error conditionslist the SCRAM users.