user.cc 5.3 KB
Newer Older
1
// Copyright (C) 2013-2015,2017 Internet Systems Consortium, Inc. ("ISC")
2
//
3 4 5
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 7 8 9

#include <dhcp/hwaddr.h>
#include <dhcp/duid.h>
#include <exceptions/exceptions.h>
10
#include <util/encode/hex.h>
11 12 13 14 15 16

#include <user.h>

#include <iomanip>
#include <sstream>

17 18
namespace user_chk {

19
//********************************* UserId ******************************
20

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
const char* UserId::HW_ADDRESS_STR = "HW_ADDR";
const char* UserId::DUID_STR = "DUID";

UserId::UserId(UserIdType id_type, const std::vector<uint8_t>& id)
    : id_type_(id_type), id_(id) {
    if (id.size() == 0) {
        isc_throw(isc::BadValue, "UserId id may not be blank");
    }
}

UserId::UserId(UserIdType id_type, const std::string & id_str) :
    id_type_(id_type) {
    if (id_str.empty()) {
        isc_throw(isc::BadValue, "UserId id string may not be blank");
    }

37 38
    // Convert the id string to vector.
    // Input is expected to be 2-digits per bytes, no delimiters.
39
    std::vector<uint8_t> addr_bytes;
40

41
    // Strip out colon delimiters, decodeHex doesn't like them.
42 43 44 45 46 47
    std::string clean_id_str = id_str;
    std::string::iterator end_pos = std::remove(clean_id_str.begin(),
                                                clean_id_str.end(), ':');
    clean_id_str.erase(end_pos, clean_id_str.end());

    isc::util::encode::decodeHex(clean_id_str, addr_bytes);
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

    // Attempt to instantiate the appropriate id class to leverage validation.
    switch (id_type) {
        case HW_ADDRESS: {
            isc::dhcp::HWAddr hwaddr(addr_bytes, isc::dhcp::HTYPE_ETHER);
            break;
            }
        case DUID: {
            isc::dhcp::DUID duid(addr_bytes);
            break;
            }
        default:
            isc_throw (isc::BadValue, "Invalid id_type: " << id_type);
            break;
    }

    // It's a valid id.
    id_ = addr_bytes;
}

UserId::~UserId() {
}

const std::vector<uint8_t>&
UserId::getId() const {
    return (id_);
}

UserId::UserIdType
UserId::getType() const {
    return (id_type_);
}

std::string
UserId::toText(char delim_char) const {
    std::stringstream tmp;
    tmp << std::hex;
    bool delim = false;
    for (std::vector<uint8_t>::const_iterator it = id_.begin();
         it != id_.end(); ++it) {
        if (delim_char && delim) {
            tmp << delim_char;
        }

        tmp << std::setw(2) << std::setfill('0')
            << static_cast<unsigned int>(*it);
        delim = true;
    }

    return (tmp.str());
}

bool
UserId::operator ==(const UserId & other) const {
    return ((this->id_type_ == other.id_type_) && (this->id_ == other.id_));
}

bool
UserId::operator !=(const UserId & other) const {
    return (!(*this == other));
}

bool
UserId::operator <(const UserId & other) const {
112 113
    return ((this->id_type_ < other.id_type_) ||
            ((this->id_type_ == other.id_type_) && (this->id_ < other.id_)));
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
}

std::string
UserId::lookupTypeStr(UserIdType type) {
    const char* tmp = NULL;
    switch (type) {
        case HW_ADDRESS:
            tmp = HW_ADDRESS_STR;
            break;
        case DUID:
            tmp = DUID_STR;
            break;
        default:
            isc_throw(isc::BadValue, "Invalid UserIdType:" << type);
            break;
    }

    return (std::string(tmp));
}

UserId::UserIdType
UserId::lookupType(const std::string& type_str) {
136
    if (type_str.compare(HW_ADDRESS_STR) == 0) {
137
        return (HW_ADDRESS);
138
    } else if (type_str.compare(DUID_STR) == 0) {
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
        return (DUID);
    }

    isc_throw(isc::BadValue, "Invalid UserIdType string:" << type_str);
}

std::ostream&
operator<<(std::ostream& os, const UserId& user_id) {
    std::string tmp = UserId::lookupTypeStr(user_id.getType());
    os << tmp << "=" << user_id.toText();
    return (os);
}

//********************************* User ******************************

User::User(const UserId& user_id) : user_id_(user_id) {
}

User::User(UserId::UserIdType id_type, const std::vector<uint8_t>& id)
    : user_id_(id_type, id) {
}

161
User::User(UserId::UserIdType id_type, const std::string& id_str)
162 163 164 165 166 167
    : user_id_(id_type, id_str) {
}

User::~User() {
}

168 169 170 171 172 173 174 175 176 177
const PropertyMap&
User::getProperties() const {
    return (properties_);
}

void
User::setProperties(const PropertyMap& properties) {
    properties_ = properties;
}

178 179 180 181 182
void User::setProperty(const std::string& name, const std::string& value) {
    if (name.empty()) {
        isc_throw (isc::BadValue, "User property name cannot be blank");
    }

183
    // Note that if the property exists its value will be updated.
184 185 186 187 188 189 190 191 192 193
    properties_[name]=value;
}

std::string
User::getProperty(const std::string& name) const {
    PropertyMap::const_iterator it = properties_.find(name);
    if (it != properties_.end()) {
        return ((*it).second);
    }

194 195 196
    // By returning an empty string rather than throwing, we allow the
    // flexibility of defaulting to blank if not specified.  Let the caller
    // decide if that is valid or not.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    return ("");
}

void
User::delProperty(const std::string & name) {
    PropertyMap::iterator it = properties_.find(name);
    if (it != properties_.end()) {
        properties_.erase(it);
    }
}

const UserId&
User::getUserId() const {
    return (user_id_);
}
212 213

} // namespace user_chk