From patchwork Fri Jun 1 02:50:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?5bCk56uL5a6H?= X-Patchwork-Id: 578 Return-Path: Delivered-To: patchwork@archlinux.org Received: from apollo.archlinux.org (localhost [127.0.0.1]) by apollo.archlinux.org (Postfix) with ESMTP id 0A3674827185 for ; Fri, 1 Jun 2018 02:52:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on apollo X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=DKIM_ADSP_CUSTOM_MED=0.001, DKIM_SIGNED=0.1,FREEMAIL_FROM=0.5,MAILING_LIST_MULTI=-1, RCVD_IN_DNSWL_MED=-2.3,T_DKIM_INVALID=1 autolearn=ham autolearn_force=no version=3.4.1 X-Spam-BL-Results: [127.0.9.2] Received: from orion.archlinux.org (orion.archlinux.org [88.198.91.70]) by apollo.archlinux.org (Postfix) with ESMTPS for ; Fri, 1 Jun 2018 02:52:08 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 2CDCEAE44B130; Fri, 1 Jun 2018 02:52:02 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [5.9.250.164]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS; Fri, 1 Jun 2018 02:52:02 +0000 (UTC) Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id 05EE32BFC0; Fri, 1 Jun 2018 02:52:02 +0000 (UTC) Authentication-Results: luna.archlinux.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Aov1aqxD Received: from luna.archlinux.org (luna.archlinux.org [127.0.0.1]) by luna.archlinux.org (Postfix) with ESMTP id BFF292BFC0 for ; Fri, 1 Jun 2018 02:51:59 +0000 (UTC) Received: from orion.archlinux.org (orion.archlinux.org [IPv6:2a01:4f8:160:6087::1]) by luna.archlinux.org (Postfix) with ESMTPS for ; Fri, 1 Jun 2018 02:51:59 +0000 (UTC) Received: from orion.archlinux.org (localhost [127.0.0.1]) by orion.archlinux.org (Postfix) with ESMTP id 017E6AE44B12E for ; Fri, 1 Jun 2018 02:51:54 +0000 (UTC) Received: from mail-pl0-x22b.google.com (mail-pl0-x22b.google.com [IPv6:2607:f8b0:400e:c01::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by orion.archlinux.org (Postfix) with ESMTPS for ; Fri, 1 Jun 2018 02:51:53 +0000 (UTC) Received: by mail-pl0-x22b.google.com with SMTP id 31-v6so4481060plc.4 for ; Thu, 31 May 2018 19:51:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QVh1y4CB2b/HD2s9hjgKiXe+29y/QgBSgXCqWX+G+KM=; b=Aov1aqxDZGOlDprLSCGAxqbFQnEZoCKgv6po/Fm2YVQjkvKZf845ZBdtJBeGManLM7 p/GJ0bWllVF/EQsSOU1qIf0kWyNxnpmj8pktJQqszdTYmg1bxf+9zVBduOMb4W+JLr8H R96JPLGeCZDSE5uwDAcBQ/jdPHWJLgiTS02tiJFhUvGRQp/TLoXXTjQPb4obsu1E6wWT 5bFTfpi3+9pkxnZB1YGsxwgDcsSiHjJh9+QBf1GukQ+8xIUwPgRPsQ+38dflHAn2rhRy mvbaY8+jLOuROL0S5GfXZXWzV188ipvV5QrHGI1B897BH+QJoMvbGJ5wNDegXVll6H6Q kfLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=QVh1y4CB2b/HD2s9hjgKiXe+29y/QgBSgXCqWX+G+KM=; b=TIxKgcYy1bA2os2aZ+xUEPXBKv7BUuwDjmZAVINM4/CTRPjNSCMkf5GVt5WSa+Gx0b BuN3EZpxEDeIQC2tGMMA8mLNWZqH3RVtr5C5hgTJz+R5xnPG2SD+8bK6lD5F2W+N25PC ODg133DfA10dBM7UysuHWCBJGGN4/s1P3HCSU9Zjfxtwz6U8Ek3KbIcJKChFL8jSAGei 1Ika1nPqtfAsXw5C7Y4n/TqFjQPrS8gpcbrDd9vZaKTVVBjQknrUT92ns+U3nG2DUd/k m5XyArWDFiYcVaOVbVIbZuGXXPK4dOHd2eXQmR3OR5CMIy9ZNpRkzj3bKymy+gv7dwGV 3R3g== X-Gm-Message-State: ALKqPwe+Nhrqi/HnMdoX6zjIZbMowII8W6HqxTtt1SS1K9hEZjNOG4UF 1/cZc+CrdWA18LFdu2zZUMhsEA== X-Google-Smtp-Source: ADUXVKIp1FaQzhkq5RdMUPs+X6TI9ONN7cM3unSzwKcld6NNSrhQxyfxmn39hWRkfZZHMeYatzxq7Q== X-Received: by 2002:a17:902:6b8b:: with SMTP id p11-v6mr9224565plk.212.1527821511747; Thu, 31 May 2018 19:51:51 -0700 (PDT) Received: from gengar.ccu.edu.tw ([140.123.56.58]) by smtp.gmail.com with ESMTPSA id r79-v6sm27512681pfe.115.2018.05.31.19.51.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 31 May 2018 19:51:50 -0700 (PDT) From: Li-Yu Yu To: aur-dev@archlinux.org Subject: [PATCH] add rpc v6: support multiple _by_ fields Date: Fri, 1 Jun 2018 10:50:55 +0800 Message-Id: <20180601025055.6938-1-afg984@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <152230098326.25318.11919775333759781073@typhoon> References: <152230098326.25318.11919775333759781073@typhoon> X-BeenThere: aur-dev@archlinux.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Arch User Repository \(AUR\) Development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: aur-dev-bounces@archlinux.org Sender: "aur-dev" --- web/lib/aurjson.class.php | 125 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 120 insertions(+), 5 deletions(-) diff --git a/web/lib/aurjson.class.php b/web/lib/aurjson.class.php index c51e9c2..db11117 100644 --- a/web/lib/aurjson.class.php +++ b/web/lib/aurjson.class.php @@ -20,6 +20,14 @@ class AurJSON { 'name', 'name-desc', 'maintainer', 'depends', 'makedepends', 'checkdepends', 'optdepends' ); + private static $exposed_fields_v6 = array( + 'name', 'description', 'maintainer', 'provides', + ); + private static $exposed_fields_map_v6 = array( + 'name' => 'Packages.Name', + 'description' => 'Packages.Description', + 'maintainer' => 'Packages.Maintainer', + ); private static $exposed_depfields = array( 'depends', 'makedepends', 'checkdepends', 'optdepends' ); @@ -80,7 +88,7 @@ class AurJSON { if (isset($http_data['v'])) { $this->version = intval($http_data['v']); } - if ($this->version < 1 || $this->version > 5) { + if ($this->version < 1 || $this->version > 6) { return $this->json_error('Invalid version specified.'); } @@ -94,8 +102,21 @@ class AurJSON { if (isset($http_data['search_by']) && !isset($http_data['by'])) { $http_data['by'] = $http_data['search_by']; } - if (isset($http_data['by']) && !in_array($http_data['by'], self::$exposed_fields)) { - return $this->json_error('Incorrect by field specified.'); + if (isset($http_data['by'])) { + if ($this->version < 6) { + if (!in_array($http_data['by'], self::$exposed_fields)) { + return $this->json_error('Incorrect by field specified.'); + } + } else { + if (!is_array($http_data['by'])) { + $http_data['by'] = array($http_data['by']); + } + foreach ($http_data['by'] as $by) { + if (!in_array($by, self::$exposed_fields_v6)) { + return $this->json_error("Incorrect by field '$by' specified."); + } + } + } } $this->dbh = DB::connect(); @@ -109,7 +130,11 @@ class AurJSON { if ($type == 'info' && $this->version >= 5) { $type = 'multiinfo'; } - $json = call_user_func(array(&$this, $type), $http_data); + if ($this->version < 6) { + $json = call_user_func(array(&$this, $type), $http_data); + } else { + $json = $this->info_search_v6($type, $http_data); + } $etag = md5($json); header("Etag: \"$etag\""); @@ -374,6 +399,21 @@ class AurJSON { } $result = $this->dbh->query($query); + return $this->process_result($type, $result); + } + + + /* + * Retrieve package information from a dbh->query result + * + * @param $type The request type. + * @param $result A dbh->query result. + * + * @return mixed Returns an array of package matches. + */ + private function process_result($type, $result) { + $max_results = config_get_int('options', 'max_rpc_results'); + if ($result) { $resultcount = 0; $search_data = array(); @@ -515,6 +555,82 @@ class AurJSON { return $this->process_query('search', $where_condition); } + /* + * Performs a info or search query to the package database. + * + * @param $type The request type. + * @param array $http_data Query parameters. + * + * @return mixed Returns an array of package matches. + */ + private function info_search_v6($type, $http_data) { + if (isset($http_data['by'])) { + $query_by = $http_data['by']; + if (!is_array($query_by)) { + $query_by = array($query_by); + } + } else { + if ($type == "multiinfo") { + $query_by = array('name'); + } else { // search + $query_by = array('name', 'description'); + } + } + + if ($type == "multiinfo") { + $args = $http_data['arg']; + if (!is_array($args)) { + $args = array($args); + } + foreach ($args as $i => $arg) { + $args[$i] = $this->dbh->quote($arg); + } + $op_rhs = " IN (" . implode(",", $args) . ")"; + } else { + $keyword_string = $http_data['arg']; + $keyword_string = $this->dbh->quote("%" . addcslashes($keyword_string, '%_') . "%"); + $op_rhs = " LIKE " . $keyword_string; + } + + $has_provides_query = false; + $where_condition = ""; + foreach ($query_by as $index => $by) { + if ($index != 0) { + $where_condition .= " OR "; + } + if ($by == "provides") { + $has_provides_query = true; + $where_condition .= "(RelationTypes.Name = 'provides' AND "; + $where_condition .= "PackageRelations.RelName $op_rhs)"; + } else { + $where_condition .= self::$exposed_fields_map_v6[$by]; + $where_condition .= $op_rhs; + } + } + + $max_results = config_get_int('options', 'max_rpc_results'); + $fields = implode(',', self::$fields_v4); + $q = "SELECT {$fields} " . + "FROM Packages LEFT JOIN PackageBases " . + "ON PackageBases.ID = Packages.PackageBaseID " . + "LEFT JOIN Users " . + "ON PackageBases.MaintainerUID = Users.ID "; + if ($has_provides_query) { + $q .= "LEFT JOIN PackageRelations ON PackageRelations.PackageID = Packages.ID "; + $q .= "LEFT JOIN RelationTypes ON RelationTypes.ID = PackageRelations.RelTypeID "; + } + $q .= "WHERE ${where_condition} "; + $q .= "AND PackageBases.PackagerUID IS NOT NULL "; + if ($has_provides_query) { + $q .= "GROUP BY Packages.ID "; + } + $q .= "LIMIT $max_results"; + + $result = $this->dbh->query($q); + + return $this->process_result($type, $result); + } + /* * Returns the info on a specific package. * @@ -680,4 +796,3 @@ class AurJSON { return json_encode($output); } } -