<commit_before>use v6;

use MongoDB;

use BSON::Document;
use Base64;
use OpenSSL::Digest;

#-------------------------------------------------------------------------------
unit package MongoDB:auth<github:MARTIMM>;

#-----------------------------------------------------------------------------
# Class definition to do authentication with
class Authenticate::Scram {

  has ClientType $!client;
  has DatabaseType $!database;
  has Int $!conversation-id;

  #-----------------------------------------------------------------------------
  # deprecated?
  multi submethod BUILD ( ClientType:D :$client, Str :$db-name ) {
    $!client = $client;
    $!database = $!client.database(?$db-name ?? $db-name !! 'admin' );
  }

  #-----------------------------------------------------------------------------
  multi submethod BUILD ( :$!database ) { }

  #-----------------------------------------------------------------------------
  # send client first message to server and return server response
  method client-first ( Str:D $client-first-message --> Str ) {

    my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslStart => 1,
        mechanism => 'SCRAM-SHA-1',
        payload => encode-base64( $client-first-message, :str)
      )
    );

    if $doc<ok> {
      debug-message("SCRAM-SHA1 client first message");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
      return '';
    }

    $!conversation-id = $doc<conversationId>;
    Buf.new(decode-base64($doc<payload>)).decode;
  }

  #-----------------------------------------------------------------------------
  method client-final ( Str:D $client-final-message --> Str ) {

   my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslContinue => 1,
        conversationId => $!conversation-id,
        payload => encode-base64( $client-final-message, :str)
      )
    );

    if $doc<ok> {
      debug-message("SCRAM-SHA1 client final message");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
      return '';
    }

    Buf.new(decode-base64($doc<payload>)).decode;
  }

  #-----------------------------------------------------------------------------
  method mangle-password ( Str:D :$username, Str:D :$password --> Str ) {

    my utf8 $mdb-hashed-pw = ($username ~ ':mongo:' ~ $password).encode;
    #my Str $md5-mdb-hashed-pw = md5($mdb-hashed-pw).>>.fmt('%02x').join;
    #Buf.new($md5-mdb-hashed-pw.encode);
    md5($mdb-hashed-pw).>>.fmt('%02x').join;
  }

  #-----------------------------------------------------------------------------
  method cleanup ( ) {

    # Some extra chit-chat
    my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslContinue => 1,
        conversationId => $!conversation-id,
        payload => encode-base64( '', :str)
      )
    );

    if $doc<ok> {
      info-message("SCRAM-SHA1 autentication successfull");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
    }
  }

  #-----------------------------------------------------------------------------
  method error ( Str:D $message --> Str ) {
try {
    error-message($message);
CATCH { .note; }
}
  }
}<commit_msg>try and catch permanent set. because otherwise wrong messages are shown.<commit_after>use v6;

use MongoDB;

use BSON::Document;
use Base64;
use OpenSSL::Digest;

#-------------------------------------------------------------------------------
unit package MongoDB:auth<github:MARTIMM>;

#-----------------------------------------------------------------------------
# Class definition to do authentication with
class Authenticate::Scram {

  has ClientType $!client;
  has DatabaseType $!database;
  has Int $!conversation-id;

  #-----------------------------------------------------------------------------
  # deprecated?
  multi submethod BUILD ( ClientType:D :$client, Str :$db-name ) {
    $!client = $client;
    $!database = $!client.database(?$db-name ?? $db-name !! 'admin' );
  }

  #-----------------------------------------------------------------------------
  multi submethod BUILD ( :$!database ) { }

  #-----------------------------------------------------------------------------
  # send client first message to server and return server response
  method client-first ( Str:D $client-first-message --> Str ) {

    my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslStart => 1,
        mechanism => 'SCRAM-SHA-1',
        payload => encode-base64( $client-first-message, :str)
      )
    );

    if $doc<ok> {
      debug-message("SCRAM-SHA1 client first message");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
      return '';
    }

    $!conversation-id = $doc<conversationId>;
    Buf.new(decode-base64($doc<payload>)).decode;
  }

  #-----------------------------------------------------------------------------
  method client-final ( Str:D $client-final-message --> Str ) {

   my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslContinue => 1,
        conversationId => $!conversation-id,
        payload => encode-base64( $client-final-message, :str)
      )
    );

    if $doc<ok> {
      debug-message("SCRAM-SHA1 client final message");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
      return '';
    }

    Buf.new(decode-base64($doc<payload>)).decode;
  }

  #-----------------------------------------------------------------------------
  method mangle-password ( Str:D :$username, Str:D :$password --> Str ) {

    my utf8 $mdb-hashed-pw = ($username ~ ':mongo:' ~ $password).encode;
    #my Str $md5-mdb-hashed-pw = md5($mdb-hashed-pw).>>.fmt('%02x').join;
    #Buf.new($md5-mdb-hashed-pw.encode);
    md5($mdb-hashed-pw).>>.fmt('%02x').join;
  }

  #-----------------------------------------------------------------------------
  method cleanup ( ) {

    # Some extra chit-chat
    my BSON::Document $doc = $!database.run-command( BSON::Document.new: (
        saslContinue => 1,
        conversationId => $!conversation-id,
        payload => encode-base64( '', :str)
      )
    );

    if $doc<ok> {
      info-message("SCRAM-SHA1 autentication successfull");
    }

    else {
      error-message("$doc<code>, $doc<errmsg>");
    }
  }

  #-----------------------------------------------------------------------------
  method error ( Str:D $message --> Str ) {
    try {
      error-message($message);
      CATCH { .note; }
    }
  }
}
{'fraction_non_alphanumeric': 0.3493624212628668, 'fraction_numerical': 0.008910738976801351, 'mean_word_length': 1.352728586917239, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4420947', 'n_tokens_mistral': 1903, 'n_tokens_neox': 1829, 'n_words': 352}