Kea 2.5.4
user_file.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2022 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
17namespace user_chk {
18
19UserFile::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
29void
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
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
66UserFile::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
137bool
139 return (file_.is_open());
140}
141
142void
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
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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:798
A standard Data module exception that is thrown if a parse error is encountered when constructing an ...
Definition: data.h:49
Thrown a UserFile encounters an error.
Definition: user_file.h:22
static const size_t USER_ENTRY_MAX_LEN
Maximum length of a single user entry.
Definition: user_file.h:63
virtual UserPtr readNextUser()
Fetches the next user from the file.
Definition: user_file.cc:44
virtual void close()
Closes the underlying file.
Definition: user_file.cc:143
UserFile(const std::string &fname)
Constructor.
Definition: user_file.cc:19
UserPtr makeUser(const std::string &user_string)
Creates a new User instance from JSON text.
Definition: user_file.cc:66
virtual bool isOpen() const
Returns true if the file is open.
Definition: user_file.cc:138
virtual ~UserFile()
Destructor. / The destructor does call the close method.
Definition: user_file.cc:25
virtual void open()
Opens the input file for reading.
Definition: user_file.cc:30
static UserIdType lookupType(const std::string &type_str)
Returns the id type for a given text label.
Definition: user.cc:137
UserIdType
Defines the supported types of user ids.
Definition: user.h:32
Represents a unique DHCP user This class is used to represent a specific DHCP user who is identified ...
Definition: user.h:150
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:28
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
boost::shared_ptr< User > UserPtr
Defines a smart pointer to a User.
Definition: user.h:241
This file defines classes: UserId and User.
Defines the class, UserFile, which implements the UserDataSource interface for text files.