d6a07ea9e4595f541cd5495baafd7dc3632b32ad
[platform/upstream/libzypp.git] / zypp / media / CredentialFileReader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/CredentialFileReader.cc
10  *
11  */
12 #include <iostream>
13
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/InputStream.h"
16 #include "zypp/parser/IniDict.h"
17
18 #include "zypp/media/CredentialFileReader.h"
19
20 using std::endl;
21
22 #undef ZYPP_BASE_LOGGER_LOGGROUP
23 #define ZYPP_BASE_LOGGER_LOGGROUP "parser"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 {
28   ///////////////////////////////////////////////////////////////////
29   namespace media
30   {
31     ///////////////////////////////////////////////////////////////////
32     namespace
33     {
34       // Looks like INI but allows multiple sections for the same URL
35       // but different user (in .cat files). So don't use an Ini
36       // Also support a global section without '[URL]' which is used
37       // in credential files.
38       // -------------------------------------
39       // username = emptyUSER
40       // password = emptyPASS
41       // -------------------------------------
42       // [http://server/tmp/sumafake222]
43       // username = USER
44       // password = PASS
45       //
46       // [http://server/tmp/sumafake222]
47       // username = USER2
48       // password = PASS
49       // -------------------------------------
50       struct CredentialFileReaderImpl : public parser::IniParser
51       {
52         typedef CredentialFileReader::ProcessCredentials ProcessCredentials;
53
54         struct StopParsing {};
55
56         CredentialFileReaderImpl( const Pathname & input_r, const ProcessCredentials & callback_r )
57         : _input( input_r )
58         , _callback( callback_r )
59         {
60           try
61           {
62             parse( input_r );
63           }
64           catch ( StopParsing )
65           { /* NO error but consumer aborted parsing */ }
66         }
67
68         // NO-OP; new sections are opened in consume()
69         virtual void beginParse()
70         { /*EMPTY*/ }
71
72         // start a new section [url]
73         virtual void consume( const std::string & section_r )
74         {
75           endParse();   // close any open section
76           _secret.reset( new AuthData );
77           try
78           {
79             _secret->setUrl( Url(section_r) );
80           }
81           catch ( const url::UrlException & )
82           {
83             ERR << "Ignore invalid URL '" << section_r << "' in file " << _input << endl;
84             _secret.reset();    // ignore this section
85           }
86         }
87
88         virtual void consume( const std::string & section_r, const std::string & key_r, const std::string & value_r )
89         {
90           if ( !_secret && section_r.empty() )
91             _secret.reset( new AuthData );      // a initial global section without [URL]
92
93           if ( _secret )
94           {
95             if ( key_r == "username" )
96               _secret->setUsername( value_r );
97             else if ( key_r == "password" )
98               _secret->setPassword( value_r );
99             else
100               WAR << "Ignore unknown attribute '" << key_r << "=" << value_r << "' in file " << _input << endl;
101           }
102           // else: ignored section due to wrong URL
103         }
104
105         // send any valid pending section
106         virtual void endParse()
107         {
108           if ( _secret )
109           {
110             if ( _secret->valid() )
111             {
112               if ( !_callback( _secret ) )
113                 throw( StopParsing() );
114             }
115             else
116               ERR << "Ignore invalid credentials for URL '" << _secret->url() << "' in file " << _input << endl;
117           }
118         }
119
120       private:
121         const Pathname &                _input;
122         const ProcessCredentials &      _callback;
123         AuthData_Ptr                    _secret;
124       };
125     } // namespace
126     ///////////////////////////////////////////////////////////////////
127
128     //////////////////////////////////////////////////////////////////////
129     //
130     // CLASS NAME : CredentialFileReader
131     //
132     //////////////////////////////////////////////////////////////////////
133
134     CredentialFileReader::CredentialFileReader( const Pathname & crfile_r, const ProcessCredentials & callback_r )
135     { CredentialFileReaderImpl( crfile_r, callback_r ); }
136
137     CredentialFileReader::~CredentialFileReader()
138     {}
139
140   } // namespace media
141   ///////////////////////////////////////////////////////////////////
142 } // namespace zypp
143 ///////////////////////////////////////////////////////////////////
144