GME
13
|
00001 // SvnLoginDlg.cpp : implementation file 00002 // 00003 00004 #include "stdafx.h" 00005 #include "resource.h" 00006 #include "XmlBackEnd.h" 00007 #include ".\SvnLoginDlg.h" 00008 #include <io.h> 00009 #include <fstream> 00010 00011 // SvnLoginDlg dialog 00012 00013 IMPLEMENT_DYNAMIC(CSvnLoginDlg, CDialog) 00014 CSvnLoginDlg::CSvnLoginDlg( int p_prefChoice, CWnd* pParent /*=NULL*/) 00015 : CDialog(CSvnLoginDlg::IDD, pParent) 00016 , m_prefChoice( p_prefChoice) 00017 , m_aborted( false) 00018 , m_sshDisabled( false) 00019 , m_leftPad( 20) 00020 , m_rightPad( 20) 00021 , m_user(_T("")) 00022 , m_password(_T("")) 00023 , m_database(_T("")) 00024 , m_project(_T("")) 00025 , m_credRadioBtn(0) 00026 { 00027 } 00028 00029 CSvnLoginDlg::~CSvnLoginDlg() 00030 { 00031 } 00032 00033 void CSvnLoginDlg::DoDataExchange(CDataExchange* pDX) 00034 { 00035 CDialog::DoDataExchange(pDX); 00036 DDX_Text(pDX, IDC_EDIT_USER, m_user); 00037 DDX_Text(pDX, IDC_EDIT_PWD, m_password); 00038 DDX_Text(pDX, IDC_STATIC_DATABASE, m_database); 00039 DDX_Text(pDX, IDC_STATIC_PROJECT, m_project); 00040 DDX_Control(pDX, IDC_RADIO_CACHED, m_radBtnLoginMethod); 00041 DDX_Control(pDX, IDC_EDIT_USER, m_userCtrl); 00042 DDX_Control(pDX, IDC_EDIT_PWD, m_passwordCtrl); 00043 DDX_Control(pDX, IDC_LOADFROMCACHE, m_btnLoadFromCache); 00044 DDX_Radio(pDX, IDC_RADIO_CACHED, m_credRadioBtn); 00045 } 00046 00047 00048 BEGIN_MESSAGE_MAP(CSvnLoginDlg, CDialog) 00049 ON_WM_SIZE() 00050 ON_BN_CLICKED(IDC_ABORT, OnBnClickedAbort) 00051 ON_BN_CLICKED(IDC_RADIO_USPW, OnBnClickedRadioUspw) 00052 ON_BN_CLICKED(IDC_RADIO_CACHED, OnBnClickedRadioCached) 00053 ON_BN_CLICKED(IDC_RADIO_PPK, OnBnClickedRadioPpk) 00054 ON_BN_CLICKED(IDC_LOADFROMCACHE, OnBnClickedLoadFromCache) 00055 END_MESSAGE_MAP() 00056 00057 00058 // CSvnLoginDlg message handlers 00059 00060 void CSvnLoginDlg::OnSize(UINT nType, int cx, int cy) 00061 { 00062 CDialog::OnSize(nType, cx, cy); 00063 00064 CWnd * db = GetDlgItem( IDC_STATIC_DATABASE); 00065 CWnd * pj = GetDlgItem( IDC_STATIC_PROJECT); 00066 CRect db_rect, pj_rect; 00067 if( db && pj && db->GetSafeHwnd() && pj->GetSafeHwnd()) { 00068 db->GetWindowRect( &db_rect); 00069 pj->GetWindowRect( &pj_rect); 00070 ScreenToClient( &db_rect); 00071 ScreenToClient( &pj_rect); 00072 int width = cx - m_leftPad - m_rightPad; 00073 00074 db->SetWindowPos( NULL, m_leftPad, db_rect.top, width > 20? width: 20, db_rect.Height(), SWP_NOZORDER); 00075 pj->SetWindowPos( NULL, m_leftPad, pj_rect.top, width > 20? width: 20, pj_rect.Height(), SWP_NOZORDER); 00076 } 00077 } 00078 00079 BOOL CSvnLoginDlg::OnInitDialog() 00080 { 00081 CDialog::OnInitDialog(); 00082 00083 m_credRadioBtn = m_prefChoice; 00084 00085 // turn off ppk in all cases except svn+ssh 00086 CWnd* ppk = GetDlgItem( IDC_RADIO_PPK); 00087 if( ppk) ppk->EnableWindow( !m_sshDisabled); // enable also if no url to decide upon 00088 00089 m_passwordCtrl.EnableWindow( m_credRadioBtn == 1);//either 0 or 2, m_radBtnLoginMethod.GetCheck() != BST_CHECKED); 00090 m_btnLoadFromCache.EnableWindow( m_credRadioBtn == 0); 00091 00092 // wm_size related calculations 00093 CWnd * db = GetDlgItem( IDC_STATIC_DATABASE); 00094 CRect db_rect; 00095 if( db && db->GetSafeHwnd()) { 00096 db->GetWindowRect( &db_rect); 00097 ScreenToClient( &db_rect); 00098 00099 CRect win_rect; 00100 GetWindowRect( &win_rect); 00101 ScreenToClient( &win_rect); 00102 00103 m_leftPad = db_rect.left - win_rect.left; 00104 m_rightPad = win_rect.right - db_rect.right; 00105 } 00106 00107 UpdateData(FALSE); // send data modifications to controls 00108 00109 return TRUE; // return TRUE unless you set the focus to a control 00110 // EXCEPTION: OCX Property Pages should return FALSE 00111 } 00112 00113 void CSvnLoginDlg::OnBnClickedRadioUspw() 00114 { 00115 m_passwordCtrl.EnableWindow( TRUE); 00116 m_btnLoadFromCache.EnableWindow( FALSE); 00117 } 00118 00119 void CSvnLoginDlg::OnBnClickedRadioCached() 00120 { 00121 m_passwordCtrl.EnableWindow( FALSE); 00122 m_btnLoadFromCache.EnableWindow( TRUE); 00123 } 00124 00125 void CSvnLoginDlg::OnBnClickedRadioPpk() 00126 { 00127 m_passwordCtrl.EnableWindow( FALSE); 00128 m_btnLoadFromCache.EnableWindow( FALSE); 00129 } 00130 00131 void CSvnLoginDlg::OnBnClickedAbort() 00132 { 00133 m_aborted = true; 00134 EndDialog( IDCANCEL); 00135 //throw hresult_exception( E_FAIL); 00136 } 00137 00138 bool CSvnLoginDlg::wasAborted() 00139 { 00140 return m_aborted; 00141 } 00142 00143 void CSvnLoginDlg::disableSshOption() 00144 { 00145 m_sshDisabled = true; 00146 } 00147 00148 bool CSvnLoginDlg::getDataFromCache( const std::string& p_inRealm, std::string& p_realm, std::string& p_uname) 00149 { 00150 // analyzing files as "C:\Documents and Settings\zolmol\Application Data\Subversion\auth\svn.simple\f061142afd1f61e24960515448599a09" 00151 // with sample content below 00152 const char* svn_sim_path = "\\Subversion\\auth\\svn.simple"; 00153 char app_data_path[ _MAX_PATH]; 00154 if( !SHGetSpecialFolderPath( NULL, app_data_path, CSIDL_APPDATA, true)) //most likely C:\Documents and Settings<username>\Application Data 00155 return false; 00156 00157 if( 1) 00158 { 00159 char buf[_MAX_PATH]; 00160 _finddata_t fileInfo; 00161 00162 sprintf( buf, "%s%s\\*.", app_data_path, svn_sim_path); 00163 00164 long searchHandle = _findfirst( buf, &fileInfo ); 00165 long ret = searchHandle; 00166 while( ret != -1 ) 00167 { 00168 sprintf( buf, "%s%s\\%s", app_data_path, svn_sim_path, fileInfo.name ); 00169 00170 std::string _realm; 00171 std::string _uname; 00172 if( loadCacheFile( buf, _realm, _uname)) 00173 { 00174 std::string::size_type co_pos = _realm.find( ':'); 00175 std::string::size_type rb_pos = _realm.find( '>'); 00176 if( co_pos != std::string::npos && rb_pos != std::string::npos && co_pos < rb_pos) 00177 rb_pos = co_pos; // colon found indicating port number, so will cut right there 00178 00179 if( rb_pos != std::string::npos && _realm[0] == '<') 00180 { 00181 _realm = _realm.substr( 1, rb_pos - 1); 00182 if( p_inRealm.substr( 0, _realm.length()) == _realm) // found 00183 { 00184 p_realm = _realm; 00185 p_uname = _uname; 00186 return true; 00187 } 00188 } 00189 } 00190 00191 ret = _findnext( searchHandle, &fileInfo ); 00192 } 00193 _findclose( searchHandle ); 00194 } 00195 00196 return false; 00197 } 00198 00199 bool CSvnLoginDlg::loadCacheFile( const char* p_fileNamePtr, std::string& p_realm, std::string& p_uname) 00200 { 00201 // sample content of a cache file: 00202 //... 00203 //K 15 00204 //svn:realmstring 00205 //V 68 00206 //<https://svn.isis.vanderbilt.edu:443> testrepo username and password 00207 //K 8 00208 //username 00209 //V 7 00210 //zolmol2 00211 //END 00212 00213 std::string value_realmstring; 00214 std::string value_username; 00215 bool collecting_realmstring = false; 00216 bool collecting_username = false; 00217 bool found_realmstring = false; 00218 bool found_username = false; 00219 00220 enum TypeOfLine 00221 { 00222 KEY_INDICATOR 00223 ,VAL_INDICATOR 00224 ,KEY_STRING 00225 ,VAL_STRING 00226 }; 00227 00228 TypeOfLine t_of_ln = VAL_STRING; 00229 TypeOfLine t_of_prev_ln; 00230 { 00231 std::ifstream datafile; 00232 datafile.open( p_fileNamePtr, std::ios_base::in); 00233 if( datafile.is_open()) 00234 { 00235 char buff[1024]; 00236 while( datafile.getline( buff, 1024)) 00237 { 00238 std::string line( buff); 00239 if( line.empty()) 00240 continue; 00241 00242 t_of_prev_ln = t_of_ln; 00243 00244 if( line.substr( 0, 2) == "K ") 00245 t_of_ln = KEY_INDICATOR; 00246 else if( line.substr( 0, 2) == "V ") 00247 t_of_ln = VAL_INDICATOR; 00248 else if( t_of_prev_ln == KEY_INDICATOR) 00249 t_of_ln = KEY_STRING; 00250 else if( t_of_prev_ln == VAL_INDICATOR) 00251 t_of_ln = VAL_STRING; 00252 00253 if( t_of_ln == KEY_STRING && 0 == line.find( "svn:realmstring")) 00254 { 00255 collecting_realmstring = true; 00256 } 00257 else if( t_of_ln == KEY_STRING && 0 == line.find( "username")) 00258 { 00259 collecting_username = true; 00260 } 00261 00262 if( t_of_ln == VAL_STRING) 00263 { 00264 if( collecting_realmstring) 00265 value_realmstring = line, collecting_realmstring = false, found_realmstring = true; 00266 if( collecting_username) 00267 value_username = line, collecting_username = false, found_username = true; 00268 } 00269 } 00270 } 00271 datafile.close(); 00272 } 00273 00274 if( found_realmstring && found_username && !value_realmstring.empty() && !value_username.empty()) 00275 { 00276 p_realm = value_realmstring; 00277 p_uname = value_username; 00278 return true; 00279 } 00280 00281 return false; 00282 } 00283 00284 void CSvnLoginDlg::OnBnClickedLoadFromCache() 00285 { 00286 std::string uname; 00287 if( getDataFromCache( (LPCTSTR) m_database, std::string(), uname)) 00288 { 00289 m_user = uname.c_str(); 00290 UpdateData( FALSE); 00291 m_userCtrl.SetFocus(); // set the focus back to the username to allow a quick 'Enter' to be hit 00292 m_userCtrl.SetSel( 0, m_userCtrl.LineLength()); 00293 } 00294 else 00295 AfxMessageBox( "Cached credentials were not found for this server!"); 00296 }