user.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <dhcp/hwaddr.h>
  15. #include <dhcp/duid.h>
  16. #include <exceptions/exceptions.h>
  17. #include <util/encode/hex.h>
  18. #include <user.h>
  19. #include <iomanip>
  20. #include <sstream>
  21. //********************************* UserId ******************************
  22. const char* UserId::HW_ADDRESS_STR = "HW_ADDR";
  23. const char* UserId::DUID_STR = "DUID";
  24. UserId::UserId(UserIdType id_type, const std::vector<uint8_t>& id)
  25. : id_type_(id_type), id_(id) {
  26. if (id.size() == 0) {
  27. isc_throw(isc::BadValue, "UserId id may not be blank");
  28. }
  29. }
  30. UserId::UserId(UserIdType id_type, const std::string & id_str) :
  31. id_type_(id_type) {
  32. if (id_str.empty()) {
  33. isc_throw(isc::BadValue, "UserId id string may not be blank");
  34. }
  35. // Convert the id string to vector.
  36. // Input is expected to be 2-digits per bytes, no delimiters.
  37. std::vector<uint8_t> addr_bytes;
  38. isc::util::encode::decodeHex(id_str, addr_bytes);
  39. // Attempt to instantiate the appropriate id class to leverage validation.
  40. switch (id_type) {
  41. case HW_ADDRESS: {
  42. isc::dhcp::HWAddr hwaddr(addr_bytes, isc::dhcp::HTYPE_ETHER);
  43. break;
  44. }
  45. case DUID: {
  46. isc::dhcp::DUID duid(addr_bytes);
  47. break;
  48. }
  49. default:
  50. isc_throw (isc::BadValue, "Invalid id_type: " << id_type);
  51. break;
  52. }
  53. // It's a valid id.
  54. id_ = addr_bytes;
  55. }
  56. UserId::~UserId() {
  57. }
  58. const std::vector<uint8_t>&
  59. UserId::getId() const {
  60. return (id_);
  61. }
  62. UserId::UserIdType
  63. UserId::getType() const {
  64. return (id_type_);
  65. }
  66. std::string
  67. UserId::toText(char delim_char) const {
  68. std::stringstream tmp;
  69. tmp << std::hex;
  70. bool delim = false;
  71. for (std::vector<uint8_t>::const_iterator it = id_.begin();
  72. it != id_.end(); ++it) {
  73. if (delim_char && delim) {
  74. tmp << delim_char;
  75. }
  76. tmp << std::setw(2) << std::setfill('0')
  77. << static_cast<unsigned int>(*it);
  78. delim = true;
  79. }
  80. return (tmp.str());
  81. }
  82. bool
  83. UserId::operator ==(const UserId & other) const {
  84. return ((this->id_type_ == other.id_type_) && (this->id_ == other.id_));
  85. }
  86. bool
  87. UserId::operator !=(const UserId & other) const {
  88. return (!(*this == other));
  89. }
  90. bool
  91. UserId::operator <(const UserId & other) const {
  92. return ((this->id_type_ < other.id_type_) ||
  93. ((this->id_type_ == other.id_type_) && (this->id_ < other.id_)));
  94. }
  95. std::string
  96. UserId::lookupTypeStr(UserIdType type) {
  97. const char* tmp = NULL;
  98. switch (type) {
  99. case HW_ADDRESS:
  100. tmp = HW_ADDRESS_STR;
  101. break;
  102. case DUID:
  103. tmp = DUID_STR;
  104. break;
  105. default:
  106. isc_throw(isc::BadValue, "Invalid UserIdType:" << type);
  107. break;
  108. }
  109. return (std::string(tmp));
  110. }
  111. UserId::UserIdType
  112. UserId::lookupType(const std::string& type_str) {
  113. if (type_str.compare(HW_ADDRESS_STR) == 0) {
  114. return (HW_ADDRESS);
  115. } else if (type_str.compare(DUID_STR) == 0) {
  116. return (DUID);
  117. }
  118. isc_throw(isc::BadValue, "Invalid UserIdType string:" << type_str);
  119. }
  120. std::ostream&
  121. operator<<(std::ostream& os, const UserId& user_id) {
  122. std::string tmp = UserId::lookupTypeStr(user_id.getType());
  123. os << tmp << "=" << user_id.toText();
  124. return (os);
  125. }
  126. //********************************* User ******************************
  127. User::User(const UserId& user_id) : user_id_(user_id) {
  128. }
  129. User::User(UserId::UserIdType id_type, const std::vector<uint8_t>& id)
  130. : user_id_(id_type, id) {
  131. }
  132. User::User(UserId::UserIdType id_type, const std::string& id_str)
  133. : user_id_(id_type, id_str) {
  134. }
  135. User::~User() {
  136. }
  137. const PropertyMap&
  138. User::getProperties() const {
  139. return (properties_);
  140. }
  141. void
  142. User::setProperties(const PropertyMap& properties) {
  143. properties_ = properties;
  144. }
  145. void User::setProperty(const std::string& name, const std::string& value) {
  146. if (name.empty()) {
  147. isc_throw (isc::BadValue, "User property name cannot be blank");
  148. }
  149. // Note that if the property exists its value will be updated.
  150. properties_[name]=value;
  151. }
  152. std::string
  153. User::getProperty(const std::string& name) const {
  154. PropertyMap::const_iterator it = properties_.find(name);
  155. if (it != properties_.end()) {
  156. return ((*it).second);
  157. }
  158. // By returning an empty string rather than throwing, we allow the
  159. // flexibility of defaulting to blank if not specified. Let the caller
  160. // decide if that is valid or not.
  161. return ("");
  162. }
  163. void
  164. User::delProperty(const std::string & name) {
  165. PropertyMap::iterator it = properties_.find(name);
  166. if (it != properties_.end()) {
  167. properties_.erase(it);
  168. }
  169. }
  170. const UserId&
  171. User::getUserId() const {
  172. return (user_id_);
  173. }