<commit_before>require 'approval'
require 'rumbster'
require 'message_observers'
require 'net/imap'
require_relative '../../../utils/sli_utils.rb'

Before do 
  
end

After do |scenario|
  @rumbster.stop if @rumbster
  sleep(1)
end

Given /^I have a "([^"]*)" SMTP\/Email server configured$/ do |live_or_mock|
  sender_email_address = "<EMAIL>"
  @email_name = "SLC Admin"
  test_port = 2525
  @mode = (live_or_mock == "live")
  
  if @mode
    @email_conf = {
      :host => 'mon.slidev.org',
      :port => 3000,
      :sender_name => @email_name,
      :sender_email_addr => sender_email_address
    }
  else
    @rumbster = Rumbster.new(test_port)
    @message_observer = MailMessageObserver.new
    @rumbster.add_observer @message_observer
    @rumbster.start
    @email_conf = {
      :host => '127.0.0.1',
      :port => test_port,
      :sender_name => @email_name,
      :sender_email_addr => sender_email_address
    }
  end
end

Given /^a ([^"]*) account request for vendor "([^"]*)"$/ do |environment, vendor|
  if defined? @userinfo
    @userinfo[:vendor] = vendor
  else
    @userinfo = Hash.new
    @userinfo[:vendor] = vendor
  end

  @prod = (environment == "production")
end

Given /^first name "([^"]*)" and last name "([^"]*)"$/ do |first_name, last_name|
  @userinfo[:first] = first_name
  @userinfo[:last]  = last_name
end

Given /^login name "([^"]*)" ([^"]*) in the account request queue$/ do |email, status|
  intializaApprovalEngineAndLDAP(@email_conf, @prod)
  if @mode
    @userinfo[:email] = "<EMAIL>"
  else
    @userinfo[:email] = email
  end
  
  @userinfo[:password] = "<PASSWORD>"
  @userinfo[:emailtoken] = "<PASSWORD>"
  @userinfo[:homedir] = "test"
  @userinfo[:uidnumber] = "500"
  @userinfo[:gidnumber] = "500"
  
  # delete if there and create a new user to set fixture
  ApprovalEngine.remove_user(@userinfo[:email])
  ApprovalEngine.add_disabled_user(@userinfo)
  
  # set status manually to pending to test Approval Engine transitions
  if @prod
    if(status == ApprovalEngine::STATE_PENDING)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
    end
    if(status == ApprovalEngine::STATE_APPROVED)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_APPROVE, true)
    end
  else #it is sandbox
    # verifying the email puts user in pending state which sends the email and goes directly to approved state
    if(status == ApprovalEngine::STATE_APPROVED)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
    end
  end
  assert(@ldap.read_user(@userinfo[:email])[:status] == status, "User #{email} is not in #{status} state")
end

When /^I approve the account request$/ do
  @time = Time.now.getutc
  ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_APPROVE)
  state = @ldap.read_user(@userinfo[:email])[:status]
  assert(state == "approved", "User #{@userinfo[:email]} is in #{state} but should be in approved state")
end

Then /^a new account is created in ([^"]*) LDAP with login name "([^"]*)" and the role is "([^"]*)"$/ do |environment, login_name, role|
  login_name = "<EMAIL>" if @mode
  assert(@ldap.read_user(@userinfo[:email])[:email] == login_name, "User #{@userinfo[:email]} is not created in LDAP")
  assert(@ldap.get_user_groups(@userinfo[:email])[0] == role, "User #{@userinfo[:email]} is does not have role #{role}")
end

Then /^an email is sent to the requestor with a link to the application registration tool$/ do
  verifyEmail
end

When /^I reject the account request$/ do
  ApprovalEngine.change_user_status(@userinfo[:email], "reject")
  assert(@ldap.read_user(@userinfo[:email])[:status] == "rejected", "User #{@userinfo[:email]} is in rejected state")
end

Then /^an account exists in production LDAP with login name "([^"]*)"$/ do |login_name|
  assert(ApprovalEngine.user_exists?(@userinfo[:email]), "User " << @userinfo[:email] << " does not exist in LDAP")
  #assert(ApprovalEngine.user_exists?(login_name), "User " << login_name << " does not exist in LDAP")
end

Then /^state is "([^"]*)"$/ do |state|
  user_state = @ldap.read_user(@userinfo[:email])[:status] 
  assert(user_state == state, "User #{@userinfo[:email]} is in #{user_state} but should be in #{state} state")
end

When /^I disable the account$/ do
  ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_DISABLE, true)
end

Then /^([^"]*) LDAP account with login name "([^"]*)" is set as inactive$/ do |arg1, arg2|
  assert(@ldap.read_user(@userinfo[:email])[:status] == "disabled", "User #{@userinfo[:email]} is not in disabled state")
end

Then /^an email is sent to the requestor with a link to provision sandbox and a link for sandbox application registration tool$/ do
## TODO: verify links
  verifyEmail
end

#### Common methods ##############
def intializaApprovalEngineAndLDAP(email_conf = @email_conf, prod=true)
  @ldap = LDAPStorage.new(PropLoader.getProps['ldap.hostname'], 389, "ou=DevTest,dc=slidev,dc=org", "cn=DevLDAP User, ou=People,dc=slidev,dc=org", "Y;Gtf@w{")
  
  email = Emailer.new email_conf
  ApprovalEngine.init(@ldap, email, !prod)
end

def verifyEmail
  if @mode
    defaultUser = 'devldapuser'
    defaultPassword = '<PASSWORD>{'
    imap = Net::IMAP.new('mon.slidev.org', 993, true, nil, false)
    imap.authenticate('LOGIN', defaultUser, defaultPassword)
    imap.examine('INBOX')
    
    ids = imap.search(["FROM", @email_name])
    content = imap.fetch(ids[-1], "BODY[TEXT]")[0].attr["BODY[TEXT]"]
    subject = imap.fetch(ids[-1], "BODY[HEADER.FIELDS (SUBJECT)]")[0].attr["BODY[HEADER.FIELDS (SUBJECT)]"]
    found = true if content != nil
    imap.disconnect
    assert(found, "Email was not found on SMTP server")<commit_msg>changed to use ldap base from property file for account approval test<commit_after>require 'approval'
require 'rumbster'
require 'message_observers'
require 'net/imap'
require_relative '../../../utils/sli_utils.rb'

Before do 
  
end

After do |scenario|
  @rumbster.stop if @rumbster
  sleep(1)
end

Given /^I have a "([^"]*)" SMTP\/Email server configured$/ do |live_or_mock|
  sender_email_address = "<EMAIL>"
  @email_name = "SLC Admin"
  test_port = 2525
  @mode = (live_or_mock == "live")
  
  if @mode
    @email_conf = {
      :host => 'mon.slidev.org',
      :port => 3000,
      :sender_name => @email_name,
      :sender_email_addr => sender_email_address
    }
  else
    @rumbster = Rumbster.new(test_port)
    @message_observer = MailMessageObserver.new
    @rumbster.add_observer @message_observer
    @rumbster.start
    @email_conf = {
      :host => '127.0.0.1',
      :port => test_port,
      :sender_name => @email_name,
      :sender_email_addr => sender_email_address
    }
  end
end

Given /^a ([^"]*) account request for vendor "([^"]*)"$/ do |environment, vendor|
  if defined? @userinfo
    @userinfo[:vendor] = vendor
  else
    @userinfo = Hash.new
    @userinfo[:vendor] = vendor
  end

  @prod = (environment == "production")
end

Given /^first name "([^"]*)" and last name "([^"]*)"$/ do |first_name, last_name|
  @userinfo[:first] = first_name
  @userinfo[:last]  = last_name
end

Given /^login name "([^"]*)" ([^"]*) in the account request queue$/ do |email, status|
  intializaApprovalEngineAndLDAP(@email_conf, @prod)
  if @mode
    @userinfo[:email] = "<EMAIL>"
  else
    @userinfo[:email] = email
  end
  
  @userinfo[:password] = "<PASSWORD>"
  @userinfo[:emailtoken] = "<PASSWORD>"
  @userinfo[:homedir] = "test"
  @userinfo[:uidnumber] = "500"
  @userinfo[:gidnumber] = "500"
  
  # delete if there and create a new user to set fixture
  ApprovalEngine.remove_user(@userinfo[:email])
  ApprovalEngine.add_disabled_user(@userinfo)
  
  # set status manually to pending to test Approval Engine transitions
  if @prod
    if(status == ApprovalEngine::STATE_PENDING)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
    end
    if(status == ApprovalEngine::STATE_APPROVED)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_APPROVE, true)
    end
  else #it is sandbox
    # verifying the email puts user in pending state which sends the email and goes directly to approved state
    if(status == ApprovalEngine::STATE_APPROVED)
      ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_VERIFY_EMAIL, true)
    end
  end
  assert(@ldap.read_user(@userinfo[:email])[:status] == status, "User #{email} is not in #{status} state")
end

When /^I approve the account request$/ do
  @time = Time.now.getutc
  ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_APPROVE)
  state = @ldap.read_user(@userinfo[:email])[:status]
  assert(state == "approved", "User #{@userinfo[:email]} is in #{state} but should be in approved state")
end

Then /^a new account is created in ([^"]*) LDAP with login name "([^"]*)" and the role is "([^"]*)"$/ do |environment, login_name, role|
  login_name = "<EMAIL>" if @mode
  assert(@ldap.read_user(@userinfo[:email])[:email] == login_name, "User #{@userinfo[:email]} is not created in LDAP")
  assert(@ldap.get_user_groups(@userinfo[:email])[0] == role, "User #{@userinfo[:email]} is does not have role #{role}")
end

Then /^an email is sent to the requestor with a link to the application registration tool$/ do
  verifyEmail
end

When /^I reject the account request$/ do
  ApprovalEngine.change_user_status(@userinfo[:email], "reject")
  assert(@ldap.read_user(@userinfo[:email])[:status] == "rejected", "User #{@userinfo[:email]} is in rejected state")
end

Then /^an account exists in production LDAP with login name "([^"]*)"$/ do |login_name|
  assert(ApprovalEngine.user_exists?(@userinfo[:email]), "User " << @userinfo[:email] << " does not exist in LDAP")
  #assert(ApprovalEngine.user_exists?(login_name), "User " << login_name << " does not exist in LDAP")
end

Then /^state is "([^"]*)"$/ do |state|
  user_state = @ldap.read_user(@userinfo[:email])[:status] 
  assert(user_state == state, "User #{@userinfo[:email]} is in #{user_state} but should be in #{state} state")
end

When /^I disable the account$/ do
  ApprovalEngine.change_user_status(@userinfo[:email], ApprovalEngine::ACTION_DISABLE, true)
end

Then /^([^"]*) LDAP account with login name "([^"]*)" is set as inactive$/ do |arg1, arg2|
  assert(@ldap.read_user(@userinfo[:email])[:status] == "disabled", "User #{@userinfo[:email]} is not in disabled state")
end

Then /^an email is sent to the requestor with a link to provision sandbox and a link for sandbox application registration tool$/ do
## TODO: verify links
  verifyEmail
end

#### Common methods ##############
def intializaApprovalEngineAndLDAP(email_conf = @email_conf, prod=true)
  ldap_base=PropLoader.getProps['ldap.base']
  @ldap = LDAPStorage.new(PropLoader.getProps['ldap.hostname'], 389, ldap_base, "cn=DevLDAP User, ou=People,dc=slidev,dc=org", "Y;Gtf@w{")
  
  email = Emailer.new email_conf
  ApprovalEngine.init(@ldap, email, !prod)
end

def verifyEmail
  if @mode
    defaultUser = 'devldapuser'
    defaultPassword = '<PASSWORD>{'
    imap = Net::IMAP.new('mon.slidev.org', 993, true, nil, false)
    imap.authenticate('LOGIN', defaultUser, defaultPassword)
    imap.examine('INBOX')
    
    ids = imap.search(["FROM", @email_name])
    content = imap.fetch(ids[-1], "BODY[TEXT]")[0].attr["BODY[TEXT]"]
    subject = imap.fetch(ids[-1], "BODY[HEADER.FIELDS (SUBJECT)]")[0].attr["BODY[HEADER.FIELDS (SUBJECT)]"]
    found = true if content != nil
    imap.disconnect
    assert(found, "Email was not found on SMTP server")
{'fraction_non_alphanumeric': 0.15597335806424417, 'fraction_numerical': 0.005733074782901948, 'mean_word_length': 4.744309927360775, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, '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': '6748626', 'n_tokens_mistral': 4097, 'n_tokens_neox': 3984, 'n_words': 1011}