unit abEntryPasswordDlg;

interface

uses Windows, SysUtils, Classes, Graphics, Forms, Controls, StdCtrls,
  Buttons, ActnList, comctrls, abSecurity;

type
  TdlgPassword = class(TForm)
    Label1: TLabel;
    edtPassword: TEdit;
    btnOK: TButton;
    btnCancel: TButton;
    btnSecurity: TButton;
    lblUserName: TLabel;
    ActionList1: TActionList;
    actOK: TAction;
    actSecurity: TAction;
    edtUserName: TComboBox;
    procedure actSecurityExecute(Sender: TObject);
    procedure actOKUpdate(Sender: TObject);
    procedure actOKExecute(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }
    fbRestrictToCheckOK: boolean;
    ftvUserTemplate: TabSecurityTemplate;
    ftvSecurityTemplate: TabSecurityTemplate;
    procedure CopyUserTemplate(tvSource, tvDest: TabSecurityTemplate; sUserName: string; bRestrictToCheckOK: boolean);
    function CheckUserPassword: boolean;
  end;


implementation

{$R *.DFM}

uses Dialogs, abDlgSecurity, abCript;


function TdlgPassword.CheckUserPassword: boolean;
begin
  if Assigned(ftvUserTemplate.GetUserNodeByUserName(edtUserName.Text)) and
     (ftvUserTemplate.GetUserPassword(edtUserName.Text) = TCripter.Cript(edtPassword.Text)) then
    Result := true
  else
  begin
    if Visible then
    begin
      ShowMessage('Wrong user name or password.');
      edtUserName.SetFocus;
    end;
    Result := false;
  end;
end;

procedure TdlgPassword.actSecurityExecute(Sender: TObject);
var
  frmSecurity: TfrmSecurity;
begin
  if CheckUserPassword then
  begin
    frmSecurity := TfrmSecurity.Create(nil);
    frmSecurity.ftvSecurityTemplate := ftvSecurityTemplate;
    try
      TabSecurityTemplate(frmSecurity.ftvUserTemplate).ClearTemplate;
      TabSecurityTemplate(frmSecurity.ftvUserTemplate).Images := ftvSecurityTemplate.Images;
      CopyUserTemplate(ftvUserTemplate, TabSecurityTemplate(frmSecurity.ftvUserTemplate), edtUserName.Text, fbRestrictToCheckOK);
      frmSecurity.IsSupervisor := edtUserName.Text = C_SUPERVISOR_NAME;
      edtPassword.Text := '';

      if frmSecurity.ftvUserTemplate.Items.Count > 0 then
       //v 3.0 was frmSecurity.ftvUserTemplate.Items[0].Expand(true);
          if frmSecurity.IsSupervisor then
            frmSecurity.ftvUserTemplate.Items[0].Expand(false)
          else
            frmSecurity.ftvUserTemplate.Items[0].Expand(true);

      if mrOK = frmSecurity.ShowModal then
      begin//To do
        if edtUserName.Text = C_SUPERVISOR_NAME then
          CopyUserTemplate(TabSecurityTemplate(frmSecurity.ftvUserTemplate), ftvUserTemplate, edtUserName.Text, fbRestrictToCheckOK)//Might be used as is for a user copy only as well
        else//Copy Data (Password only)
          PNodeData(ftvUserTemplate.GetUserNodeByUserName(edtUserName.Text).Item[0].Data)^ :=
             PNodeData(TabSecurityTemplate(frmSecurity.ftvUserTemplate).GetUserNodeByUserName(edtUserName.Text).Item[0].Data)^;
      end;
    finally
      //TevSecurityDialogs(Owner).ffrUserTemplate.Parent := nil;
      frmSecurity.Destroy;
    end;
  end;
end;

procedure TdlgPassword.actOKUpdate(Sender: TObject);
begin
  TAction(Sender).Enabled := length(edtUserName.Text) > 0;
end;

procedure TdlgPassword.actOKExecute(Sender: TObject);
begin
  if not CheckUserPassword then
    modalResult := mrNone;
end;

procedure TdlgPassword.CopyUserTemplate(tvSource, tvDest: TabSecurityTemplate; sUserName: string; bRestrictToCheckOK: boolean);
  procedure ParsedCopyNode(tnParentDest, tnUserSource: TTreeNode);
  var
    tnChildSource: TTreeNode;
    lpNodeData: PNodeData;
  begin
    tnParentDest := tvDest.Items.AddChild(tnParentDest, tnUserSource.Text);
    if Assigned(tnUserSource.Data) then
    begin
      new(lpNodeData);
      tnParentDest.Data := lpNodeData;
      PNodeData(tnParentDest.Data)^ := PNodeData(tnUserSource.Data)^;
      tnParentDest.ImageIndex := tnUserSource.ImageIndex;
      tnParentDest.SelectedIndex := tnUserSource.SelectedIndex;
    end;
    tnChildSource := tnUserSource.GetFirstChild;
    while Assigned(tnChildSource) do
    begin
      if ((tnChildSource.Level = 1) or (PNodeData(tnChildSource.Data)^.iID = 0)) or
         ((PNodeData(tnChildSource.Data)^.iID > 0)
          and ((not bRestrictToCheckOK) or PNodeData(tnChildSource.Data)^.bCheckOK)) then
        ParsedCopyNode(tnParentDest, tnChildSource);
      tnChildSource := tnUserSource.GetNextChild(tnChildSource);
    end;
  end;

var
  i: integer; tnUser: TTreeNode;
  sUser, sPassword: string;
  bChildlessIntermediateNodeFound: boolean;
begin
  if sUserName = C_SUPERVISOR_NAME then
  begin
    tvDest.ClearTemplate;
    CopyEntireUserTemplate(tvSource, tvDest);
  end
  else
  begin
    tnUser := tvDest.GetUserNodeByUserName(sUserName);
    if Assigned(tnUser) then
      tvDest.DeleteNode(tnUser);
    for i:= 0 to Pred(tvSource.Items.Count) do
      if tvSource.Items[i].Level = 0 then
        if tvSource.Items[i].Text = sUserName then
          ParsedCopyNode(nil, tvSource.Items[i]);
    //Removes Childless hierrachical nodes
    if bRestrictToCheckOK then
      repeat
        bChildlessIntermediateNodeFound := false;
        for i:= Pred(tvDest.Items.Count) downto 0 do
          if tvDest.GetNodeType(tvDest.Items[i], sUser, sPassword) = ntIntermediate then
            if tvDest.Items[i].Count = 0 then
            begin
              tvDest.DeleteNode(tvDest.Items[i]);
              bChildlessIntermediateNodeFound := true;
            end;
      until not bChildlessIntermediateNodeFound;
        //if tvDest.Items[i].Level >= 2 then
  end;
end;

end.

