Skip to content

Commit

Permalink
Merge branch 'devel' of https://github.com/arangodb/arangodb into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
mpv1989 committed Mar 29, 2017
2 parents 8fba5f2 + 2a6eade commit bbbf4ea
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 10 deletions.
2 changes: 1 addition & 1 deletion arangod/RestServer/DatabaseFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -902,7 +902,7 @@ TRI_vocbase_t* DatabaseFeature::useDatabaseCoordinator(TRI_voc_tick_t id) {
TRI_vocbase_t* vocbase = p.second;

if (vocbase->id() == id) {
bool result TRI_UNUSED = vocbase->use();
bool result = vocbase->use();

// if we got here, no one else can have deleted the database
TRI_ASSERT(result == true);
Expand Down
193 changes: 193 additions & 0 deletions lib/Basics/LdapUrlParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#include "LdapUrlParser.h"
#include "Basics/StringRef.h"

#include <regex>

using namespace arangodb;

std::string LdapUrlParseResult::toString() const {
std::string result("ldap://");
if (host.set) {
result.append(host.value);
if (port.set) {
result.push_back(':');
result.append(port.value);
}
}
result.push_back('/');
result.append(basedn.value);
if (searchAttribute.set) {
result.push_back('?');
result.append(searchAttribute.value);
}
if (deep.set) {
result.push_back('?');
result.append(deep.value);
}
return result;
}

LdapUrlParseResult LdapUrlParser::parse(std::string const& url) {
LdapUrlParseResult result;
parse(url, result);
return result;
}

void LdapUrlParser::parse(std::string const& url, LdapUrlParseResult& result) {
result.valid = true;

StringRef view(url);
if (view.compare("ldap://") == 0) {
// skip over initial "ldap://"
view = StringRef(view.begin() + 7);
}

if (!view.empty() && view[0] != '/') {
// we have a hostname (and probably port)
// now search for the '/' or '?' that marks the end of the host name
size_t l = view.size();
size_t pos = view.find('/');
if (pos != std::string::npos) {
l = pos;
}
pos = view.find('?');
if (pos != std::string::npos && pos < l) {
l = pos;
}

StringRef host(view.begin(), l);
size_t colon = host.find(':');
if (colon == std::string::npos) {
// no port
result.host.populate(std::string(host.begin(), host.size()));
} else {
result.host.populate(std::string(host.begin(), colon));
result.port.populate(std::string(host.begin() + colon + 1, host.size() - colon - 1));

if (!std::regex_match(result.port.value, std::regex("^[0-9]+$", std::regex::nosubs | std::regex::ECMAScript))) {
// port number must be numeric
result.valid = false;
}
}

if (!std::regex_match(result.host.value, std::regex("^[a-zA-Z0-9\\-.]+$", std::regex::nosubs | std::regex::ECMAScript))) {
// host pattern is invalid
result.valid = false;
}

view = StringRef(host.begin() + host.size());
}

// handle basedn
if (!view.empty() && view[0] == '/') {
// skip over "/"
view = StringRef(view.begin() + 1);

size_t l = view.size();
size_t pos = view.find('?');
if (pos != std::string::npos) {
l = pos;
}

StringRef basedn(view.begin(), l);
result.basedn.populate(std::string(basedn.begin(), basedn.size()));
if (basedn.empty()) {
// basedn is empty
result.valid = false;
}

if (basedn.find('/') != std::string::npos) {
// basedn contains "/"
result.valid = false;
}

view = StringRef(basedn.begin() + basedn.size());
} else {
// if there is no basedn, we cannot have anything else
if (!view.empty()) {
// no basedn but trailing things in url
result.valid = false;
}
return;
}

// handle searchAttribute
if (!view.empty() && view[0] == '?') {
// skip over "?"
view = StringRef(view.begin() + 1);

size_t l = view.size();
size_t pos = view.find('?');
if (pos != std::string::npos) {
l = pos;
}

StringRef searchAttribute(view.begin(), l);
result.searchAttribute.populate(std::string(searchAttribute.begin(), searchAttribute.size()));
if (result.searchAttribute.value.empty() ||
!std::regex_match(result.searchAttribute.value, std::regex("^[a-zA-Z0-9\\-_]+$", std::regex::nosubs | std::regex::ECMAScript))) {
// search attribute pattern is invalid
result.valid = false;
}

view = StringRef(searchAttribute.begin() + searchAttribute.size());
} else {
// if there is no searchAttribute, there must not be anything else
if (!view.empty()) {
// no search attribute pattern, but trailing characters in string
result.valid = false;
}
return;
}

// handle deep
if (!view.empty() && view[0] == '?') {
// skip over "?"
view = StringRef(view.begin() + 1);

size_t l = view.size();
size_t pos = view.find('?');
if (pos != std::string::npos) {
l = pos;
}

StringRef deep(view.begin(), l);
result.deep.populate(std::string(deep.begin(), deep.size()));
if (result.deep.value.empty() ||
!std::regex_match(result.deep.value, std::regex("^[a-zA-Z0-9\\-_]+$", std::regex::nosubs | std::regex::ECMAScript))) {
// invalid deep pattern
result.valid = false;
}

view = StringRef(deep.begin() + deep.size());
}

// we must be at the end of the string here
if (!view.empty()) {
// trailing characters in string
result.valid = false;
}
}
72 changes: 72 additions & 0 deletions lib/Basics/LdapUrlParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
////////////////////////////////////////////////////////////////////////////////

#ifndef ARANGODB_BASICS_LDAP_URL_PARSER_H
#define ARANGODB_BASICS_LDAP_URL_PARSER_H 1

#include "Basics/Common.h"

namespace arangodb {

struct LdapUrlParseResultComponent {
LdapUrlParseResultComponent() : set(false) {}
explicit LdapUrlParseResultComponent(std::string const& defaultValue)
: value(defaultValue), set(false) {}

void populate(std::string const& newValue) {
value = newValue;
set = true;
}

void populate(std::string&& newValue) {
value = std::move(newValue);
set = true;
}

std::string value;
bool set;
};

struct LdapUrlParseResult {
LdapUrlParseResult() : valid(false) {}

LdapUrlParseResultComponent host;
LdapUrlParseResultComponent port;
LdapUrlParseResultComponent basedn;
LdapUrlParseResultComponent searchAttribute;
LdapUrlParseResultComponent deep;

std::string toString() const;

bool valid;
};

class LdapUrlParser {
public:
static LdapUrlParseResult parse(std::string const& url);
static void parse(std::string const& url, LdapUrlParseResult& result);
};

}

#endif
9 changes: 0 additions & 9 deletions lib/Basics/system-compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@
#error use <Basics/Common.h>
#endif

/// @brief mark a value as unused
#if defined(__GNUC__) || defined(__GNUG__)
#define TRI_UNUSED __attribute__((unused))
#elif defined(__clang__)
#define TRI_UNUSED __attribute__((unused))
#else
#define TRI_UNUSED /* unused */
#endif

/// @brief warn if return value is unused
#if defined(__GNUC__) || defined(__GNUG__)
#define TRI_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
Expand Down
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ add_library(${LIB_ARANGO} STATIC
Basics/Exceptions.cpp
Basics/FileUtils.cpp
Basics/HybridLogicalClock.cpp
Basics/LdapUrlParser.cpp
Basics/LocalTaskQueue.cpp
Basics/Mutex.cpp
Basics/MutexLocker.cpp
Expand Down

0 comments on commit bbbf4ea

Please sign in to comment.