void HttpConnection::ProcessMessageAsync(HttpRequest& request) { Log(LogInformation, "HttpConnection", "Processing Http message"); String auth_header = request.Headers->Get("authorization"); String::SizeType pos = auth_header.FindFirstOf(" "); String username, password; if (pos != String::NPos && auth_header.SubStr(0, pos) == "Basic") { String credentials_base64 = auth_header.SubStr(pos + 1); String credentials = Base64::Decode(credentials_base64); String::SizeType cpos = credentials.FindFirstOf(":"); if (cpos != String::NPos) { username = credentials.SubStr(0, cpos); password = credentials.SubStr(cpos + 1); } } ApiUser::Ptr user; if (m_ApiUser) user = m_ApiUser; else { user = ApiUser::GetByName(username); if (!user || !user->CheckPassword(password)) user.reset(); } HttpResponse response(m_Stream, request); if (!user) { response.SetStatus(401, "Unauthorized"); response.AddHeader("Content-Type", "text/html"); response.AddHeader("WWW-Authenticate", "Basic realm=\"Icinga 2\""); String msg = "<h1>Unauthorized</h1>"; response.WriteBody(msg.CStr(), msg.GetLength()); } else { try { HttpHandler::ProcessRequest(user, request, response); } catch (const std::exception& ex) { response.SetStatus(503, "Unhandled exception"); response.AddHeader("Content-Type", "text/plain"); String errorInfo = DiagnosticInformation(ex); response.WriteBody(errorInfo.CStr(), errorInfo.GetLength()); } } response.Finish(); m_PendingRequests--; }
void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) { if (permissionFilter) *permissionFilter = nullptr; if (permission.IsEmpty()) return; bool foundPermission = false; String requiredPermission = permission.ToLower(); Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); for (const Value& item : permissions) { String permission; Function::Ptr filter; if (item.IsObjectType<Dictionary>()) { Dictionary::Ptr dict = item; permission = dict->Get("permission"); filter = dict->Get("filter"); } else permission = item; permission = permission.ToLower(); if (!Utility::Match(permission, requiredPermission)) continue; foundPermission = true; if (filter && permissionFilter) { std::vector<std::unique_ptr<Expression> > args; args.emplace_back(new GetScopeExpression(ScopeLocal)); std::unique_ptr<Expression> indexer{new IndexerExpression(std::unique_ptr<Expression>(MakeLiteral(filter)), std::unique_ptr<Expression>(MakeLiteral("call")))}; FunctionCallExpression *fexpr = new FunctionCallExpression(std::move(indexer), std::move(args)); if (!*permissionFilter) *permissionFilter = fexpr; else *permissionFilter = new LogicalOrExpression(std::unique_ptr<Expression>(*permissionFilter), std::unique_ptr<Expression>(fexpr)); } } } if (!foundPermission) { Log(LogWarning, "FilterUtility") << "Missing permission: " << requiredPermission; BOOST_THROW_EXCEPTION(ScriptError("Missing permission: " + requiredPermission)); } }
void FilterUtility::CheckPermission(const ApiUser::Ptr& user, const String& permission, Expression **permissionFilter) { if (permissionFilter) *permissionFilter = NULL; if (permission.IsEmpty()) return; bool foundPermission = false; String requiredPermission = permission.ToLower(); Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); BOOST_FOREACH(const Value& item, permissions) { String permission; Function::Ptr filter; if (item.IsObjectType<Dictionary>()) { Dictionary::Ptr dict = item; permission = dict->Get("permission"); filter = dict->Get("filter"); } else permission = item; permission = permission.ToLower(); if (!Utility::Match(permission, requiredPermission)) continue; foundPermission = true; if (filter && permissionFilter) { std::vector<Expression *> args; args.push_back(new GetScopeExpression(ScopeLocal)); FunctionCallExpression *fexpr = new FunctionCallExpression(new IndexerExpression(MakeLiteral(filter), MakeLiteral("call")), args); if (!*permissionFilter) *permissionFilter = fexpr; else *permissionFilter = new LogicalOrExpression(*permissionFilter, fexpr); } } }
bool InfoHandler::HandleRequest(const ApiUser::Ptr& user, HttpRequest& request, HttpResponse& response, const Dictionary::Ptr& params) { if (request.RequestUrl->GetPath().size() > 2) return false; if (request.RequestMethod != "GET") return false; if (request.RequestUrl->GetPath().empty()) { response.SetStatus(302, "Found"); response.AddHeader("Location", "/v1"); return true; } if (request.RequestUrl->GetPath()[0] != "v1" || request.RequestUrl->GetPath().size() != 1) return false; response.SetStatus(200, "OK"); std::vector<String> permInfo; Array::Ptr permissions = user->GetPermissions(); if (permissions) { ObjectLock olock(permissions); BOOST_FOREACH(const Value& permission, permissions) { String name; bool hasFilter = false; if (permission.IsObjectType<Dictionary>()) { Dictionary::Ptr dpermission = permission; name = dpermission->Get("permission"); hasFilter = dpermission->Contains("filter"); } else name = permission; if (hasFilter) name += " (filtered)"; permInfo.push_back(name); } }