Kea  1.9.9-git
user_file.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <cc/data.h>
10 #include <user.h>
11 #include <user_file.h>
12 
13 #include <boost/foreach.hpp>
14 #include <errno.h>
15 #include <iostream>
16 
17 namespace user_chk {
18 
19 UserFile::UserFile(const std::string& fname) : fname_(fname), file_() {
20  if (fname_.empty()) {
21  isc_throw(UserFileError, "file name cannot be blank");
22  }
23 }
24 
26  close();
27 };
28 
29 void
31  if (isOpen()) {
32  isc_throw(UserFileError, "file is already open");
33  }
34 
35  file_.open(fname_.c_str(), std::ifstream::in);
36  int sav_error = errno;
37  if (!file_.is_open()) {
38  isc_throw(UserFileError, "cannot open file:" << fname_
39  << " reason: " << strerror(sav_error));
40  }
41 }
42 
43 UserPtr
45  if (!isOpen()) {
46  isc_throw (UserFileError, "cannot read, file is not open");
47  }
48 
49  if (file_.good()) {
50  char buf[USER_ENTRY_MAX_LEN];
51 
52  // Get the next line.
53  file_.getline(buf, sizeof(buf));
54 
55  // We got something, try to make a user out of it.
56  if (file_.gcount() > 0) {
57  return(makeUser(buf));
58  }
59  }
60 
61  // Returns an empty user on EOF.
62  return (UserPtr());
63 }
64 
65 UserPtr
66 UserFile::makeUser(const std::string& user_string) {
67  // This method leverages the existing JSON parsing provided by isc::data
68  // library. Should this prove to be a performance issue, it may be that
69  // lighter weight solution would be appropriate.
70 
71  // Turn the string of JSON text into an Element set.
72  isc::data::ElementPtr elements;
73  try {
74  elements = isc::data::Element::fromJSON(user_string);
75  } catch (const isc::data::JSONError& ex) {
77  "UserFile entry is malformed JSON: " << ex.what());
78  }
79 
80  // Get a map of the Elements, keyed by element name.
82  PropertyMap properties;
83  std::string id_type_str;
84  std::string id_str;
85 
86  // Iterate over the elements, saving of "type" and "id" to their
87  // respective locals. Anything else is assumed to be an option so
88  // add it to the local property map.
89  std::pair<std::string, isc::data::ConstElementPtr> element_pair;
90  BOOST_FOREACH (element_pair, elements->mapValue()) {
91  // Get the element's label.
92  std::string label = element_pair.first;
93 
94  // Currently everything must be a string.
95  if (element_pair.second->getType() != isc::data::Element::string) {
96  isc_throw (UserFileError, "UserFile entry: " << user_string
97  << "has non-string value for : " << label);
98  }
99 
100  std::string value = element_pair.second->stringValue();
101 
102  if (label == "type") {
103  id_type_str = value;
104  } else if (label == "id") {
105  id_str = value;
106  } else {
107  // JSON parsing reduces any duplicates to the last value parsed,
108  // so we will never see duplicates here.
109  properties[label]=value;
110  }
111  }
112 
113  // First we attempt to translate the id type.
114  UserId::UserIdType id_type;
115  try {
116  id_type = UserId::lookupType(id_type_str);
117  } catch (const std::exception& ex) {
118  isc_throw (UserFileError, "UserFile entry has invalid type: "
119  << user_string << " " << ex.what());
120  }
121 
122  // Id type is valid, so attempt to make the user based on that and
123  // the value we have for "id".
124  UserPtr user;
125  try {
126  user.reset(new User(id_type, id_str));
127  } catch (const std::exception& ex) {
128  isc_throw (UserFileError, "UserFile cannot create user form entry: "
129  << user_string << " " << ex.what());
130  }
131 
132  // We have a new User, so add in the properties and return it.
133  user->setProperties(properties);
134  return (user);
135 }
136 
137 bool
139  return (file_.is_open());
140 }
141 
142 void
144  try {
145  if (file_.is_open()) {
146  file_.close();
147  }
148  } catch (const std::exception& ex) {
149  // Highly unlikely to occur but let's at least spit out an error.
150  // Beyond that we swallow it for tidiness.
151  std::cout << "UserFile unexpected error closing the file: "
152  << fname_ << " : " << ex.what() << std::endl;
153  }
154 }
155 
156 } // namespace user_chk
UserIdType
Defines the supported types of user ids.
Definition: user.h:32
Thrown a UserFile encounters an error.
Definition: user_file.h:22
virtual void close()
Closes the underlying file.
Definition: user_file.cc:143
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
Definition: data.h:43
UserFile(const std::string &fname)
Constructor.
Definition: user_file.cc:19
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition: data.cc:740
virtual bool isOpen() const
Returns true if the file is open.
Definition: user_file.cc:138
boost::shared_ptr< User > UserPtr
Defines a smart pointer to a User.
Definition: user.h:241
Defines the class, UserFile, which implements the UserDataSource interface for text files...
static const size_t USER_ENTRY_MAX_LEN
Maximum length of a single user entry.
Definition: user_file.h:63
Defines the logger used by the user check hooks library.
Definition: user.cc:19
std::map< std::string, std::string > PropertyMap
Defines a map of string values keyed by string labels.
Definition: user.h:145
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
This file defines classes: UserId and User.
Represents a unique DHCP user This class is used to represent a specific DHCP user who is identified ...
Definition: user.h:150
virtual void open()
Opens the input file for reading.
Definition: user_file.cc:30
UserPtr makeUser(const std::string &user_string)
Creates a new User instance from JSON text.
Definition: user_file.cc:66
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
static UserIdType lookupType(const std::string &type_str)
Returns the id type for a given text label.
Definition: user.cc:137
virtual ~UserFile()
Destructor. / The destructor does call the close method.
Definition: user_file.cc:25
virtual UserPtr readNextUser()
Fetches the next user from the file.
Definition: user_file.cc:44