Kea 2.5.8
user_file.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2024 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 <errno.h>
14#include <iostream>
15
16namespace user_chk {
17
18UserFile::UserFile(const std::string& fname) : fname_(fname), file_() {
19 if (fname_.empty()) {
20 isc_throw(UserFileError, "file name cannot be blank");
21 }
22}
23
25 close();
26};
27
28void
30 if (isOpen()) {
31 isc_throw(UserFileError, "file is already open");
32 }
33
34 file_.open(fname_.c_str(), std::ifstream::in);
35 int sav_error = errno;
36 if (!file_.is_open()) {
37 isc_throw(UserFileError, "cannot open file:" << fname_
38 << " reason: " << strerror(sav_error));
39 }
40}
41
44 if (!isOpen()) {
45 isc_throw (UserFileError, "cannot read, file is not open");
46 }
47
48 if (file_.good()) {
49 char buf[USER_ENTRY_MAX_LEN];
50
51 // Get the next line.
52 file_.getline(buf, sizeof(buf));
53
54 // We got something, try to make a user out of it.
55 if (file_.gcount() > 0) {
56 return(makeUser(buf));
57 }
58 }
59
60 // Returns an empty user on EOF.
61 return (UserPtr());
62}
63
65UserFile::makeUser(const std::string& user_string) {
66 // This method leverages the existing JSON parsing provided by isc::data
67 // library. Should this prove to be a performance issue, it may be that
68 // lighter weight solution would be appropriate.
69
70 // Turn the string of JSON text into an Element set.
71 isc::data::ElementPtr elements;
72 try {
73 elements = isc::data::Element::fromJSON(user_string);
74 } catch (const isc::data::JSONError& ex) {
76 "UserFile entry is malformed JSON: " << ex.what());
77 }
78
79 // Get a map of the Elements, keyed by element name.
81 PropertyMap properties;
82 std::string id_type_str;
83 std::string id_str;
84
85 // Iterate over the elements, saving of "type" and "id" to their
86 // respective locals. Anything else is assumed to be an option so
87 // add it to the local property map.
88 std::pair<std::string, isc::data::ConstElementPtr> element_pair;
89 for (auto const& element_pair : elements->mapValue()) {
90 // Get the element's label.
91 std::string label = element_pair.first;
92
93 // Currently everything must be a string.
94 if (element_pair.second->getType() != isc::data::Element::string) {
95 isc_throw (UserFileError, "UserFile entry: " << user_string
96 << "has non-string value for : " << label);
97 }
98
99 std::string value = element_pair.second->stringValue();
100
101 if (label == "type") {
102 id_type_str = value;
103 } else if (label == "id") {
104 id_str = value;
105 } else {
106 // JSON parsing reduces any duplicates to the last value parsed,
107 // so we will never see duplicates here.
108 properties[label]=value;
109 }
110 }
111
112 // First we attempt to translate the id type.
113 UserId::UserIdType id_type;
114 try {
115 id_type = UserId::lookupType(id_type_str);
116 } catch (const std::exception& ex) {
117 isc_throw (UserFileError, "UserFile entry has invalid type: "
118 << user_string << " " << ex.what());
119 }
120
121 // Id type is valid, so attempt to make the user based on that and
122 // the value we have for "id".
123 UserPtr user;
124 try {
125 user.reset(new User(id_type, id_str));
126 } catch (const std::exception& ex) {
127 isc_throw (UserFileError, "UserFile cannot create user form entry: "
128 << user_string << " " << ex.what());
129 }
130
131 // We have a new User, so add in the properties and return it.
132 user->setProperties(properties);
133 return (user);
134}
135
136bool
138 return (file_.is_open());
139}
140
141void
143 try {
144 if (file_.is_open()) {
145 file_.close();
146 }
147 } catch (const std::exception& ex) {
148 // Highly unlikely to occur but let's at least spit out an error.
149 // Beyond that we swallow it for tidiness.
150 std::cout << "UserFile unexpected error closing the file: "
151 << fname_ << " : " << ex.what() << std::endl;
152 }
153}
154
155} // 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:43
virtual void close()
Closes the underlying file.
Definition: user_file.cc:142
UserFile(const std::string &fname)
Constructor.
Definition: user_file.cc:18
UserPtr makeUser(const std::string &user_string)
Creates a new User instance from JSON text.
Definition: user_file.cc:65
virtual bool isOpen() const
Returns true if the file is open.
Definition: user_file.cc:137
virtual ~UserFile()
Destructor. / The destructor does call the close method.
Definition: user_file.cc:24
virtual void open()
Opens the input file for reading.
Definition: user_file.cc:29
static UserIdType lookupType(const std::string &type_str)
Returns the id type for a given text label.
Definition: user.cc:136
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.