Skip to content

Commit

Permalink
Try to fix tests and rewrite sql to fix sql injection
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandermeindl committed Jan 17, 2021
1 parent 45f722b commit 05990da
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 28 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,13 @@ jobs:
- name: Import PostgreSQL dump with hedgedoc
working-directory: redmine
run: |
psql hedgedoc < test/support/hedgedoc-postgres.sql
psql hedgedoc < plugins/redmine_hedgedoc/test/support/hedgedoc-postgres.sql
if: matrix.db == 'postgres'

- name: Import MySQL dump with hedgedoc
working-directory: redmine
run: |
mysql hedgedoc < test/support/hedgedoc-mysql.sql
mysql hedgedoc < plugins/redmine_hedgedoc/test/support/hedgedoc-mysql.sql
if: matrix.db == 'mysql'

- name: Run tests
Expand Down
1 change: 1 addition & 0 deletions .slim-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ linters:
ignored_cops:
- Layout/AlignArguments
- Layout/AlignArray
- Layout/ArgumentAlignment
- Layout/AlignHash
- Layout/AlignParameters
- Layout/BlockEndNewline
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/hedgedocs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def show
@hedgedoc_pad_pages = Paginator.new @hedgedoc_pad_count, @limit, params['page']
@offset ||= @hedgedoc_pad_pages.offset
@hedgedoc_pads = scope.order(HedgedocPad.fix_sort_clause(sort_clause))
.limit(@limit)
.offset(@offset)
.limit(@limit)
.offset(@offset)
end
end
54 changes: 31 additions & 23 deletions app/models/hedgedoc_pad.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,21 @@ class << self
# e.g. ["open", "test_projekt"]
def pads(project)
scope = HedgedocNote.joins(:User)
.where.not(title: nil,
Users: { email: nil })
.where.not(title: nil, Users: { email: nil })

if project
scope.where("permission!='private' OR email IN(:mails)", mails: User.current.mails)
.where('LOWER(title) LIKE ?', "#{project.identifier}:%")
else
prefixes = HedgedocPad.project_identifier
scope.where("permission!='private' OR email IN(:mails)", mails: User.current.mails)

if prefixes.present?
scope.where("permission!='private' OR email IN(:mails)", mails: User.current.mails)
sql = '(email IN(:mails))'
sql << " OR (permission!='private' AND ("
prefix_line = []
prefixes.each do |prefix|
prefix_line << "LOWER(title) LIKE '#{prefix}:%'"
end
sql << prefix_line.join(' OR ')
sql << '))'
end
scope.where(sql, mails: User.current.mails)
scope = scope.where.not(permission: 'private')
.or(scope.where(Users: { email: User.current.mails }))

like_values = project_identifier_like_values project
return scope if like_values.blank?

pscope = scope.where 'LOWER(title) LIKE ?', like_values.shift
# if more are available run loop
like_values.each do |like_value|
pscope = pscope.or(scope.where('LOWER(title) LIKE ?', like_value))
end

pscope
end

# Fix problem with PostgreSQL table names and sort_clause method
Expand All @@ -43,9 +35,25 @@ def fix_sort_clause(sort_clause)
keys
end

private

# Get all project identifier of the current user
def project_identifier
Project.where(Project.allowed_to_condition(User.current, :show_hedgedoc_pads)).pluck(:identifier)
def project_identifiers
Project.where(Project.allowed_to_condition(User.current, :show_hedgedoc_pads))
.pluck(:identifier)
end

def project_identifier_like_values(project)
likes = []
if project
likes << "#{project.identifier}:%"
else
project_identifiers.each do |identifier|
likes << "#{identifier}:%"
end
end

likes
end
end
end
1 change: 0 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
resources :projects, only: [] do
resource :hedgedoc, only: %i[show]
end

204 changes: 204 additions & 0 deletions test/support/hedgedoc-mysql.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
-- MySQL dump 10.13 Distrib 8.0.22, for osx10.16 (x86_64)
--
-- Host: localhost Database: hedgedoc
-- ------------------------------------------------------
-- Server version 8.0.22

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `Authors`
--

DROP TABLE IF EXISTS `Authors`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Authors` (
`id` int NOT NULL AUTO_INCREMENT,
`color` varchar(255) DEFAULT NULL,
`noteId` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`userId` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `Authors`
--

LOCK TABLES `Authors` WRITE;
/*!40000 ALTER TABLE `Authors` DISABLE KEYS */;
/*!40000 ALTER TABLE `Authors` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `Notes`
--

DROP TABLE IF EXISTS `Notes`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Notes` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`ownerId` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`content` longtext,
`title` text,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
`shortid` varchar(255) NOT NULL DEFAULT '0000000000',
`permission` enum('freely','editable','limited','locked','protected','private') DEFAULT NULL,
`viewcount` int DEFAULT '0',
`lastchangeuserId` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`lastchangeAt` datetime DEFAULT NULL,
`alias` varchar(255) DEFAULT NULL,
`savedAt` datetime DEFAULT NULL,
`authorship` longtext,
`deletedAt` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `notes_shortid` (`shortid`),
KEY `notes_alias` (`alias`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `Notes`
--

LOCK TABLES `Notes` WRITE;
/*!40000 ALTER TABLE `Notes` DISABLE KEYS */;
/*!40000 ALTER TABLE `Notes` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `Revisions`
--

DROP TABLE IF EXISTS `Revisions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Revisions` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`noteId` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`patch` longtext,
`lastContent` longtext,
`content` longtext,
`length` int DEFAULT NULL,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
`authorship` longtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `Revisions`
--

LOCK TABLES `Revisions` WRITE;
/*!40000 ALTER TABLE `Revisions` DISABLE KEYS */;
/*!40000 ALTER TABLE `Revisions` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `SequelizeMeta`
--

DROP TABLE IF EXISTS `SequelizeMeta`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `SequelizeMeta` (
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`name`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `SequelizeMeta`
--

LOCK TABLES `SequelizeMeta` WRITE;
/*!40000 ALTER TABLE `SequelizeMeta` DISABLE KEYS */;
INSERT INTO `SequelizeMeta` VALUES ('20150504155329-create-users.js'),('20150508114741-create-notes.js'),('20150515125813-create-temp.js'),('20150702001020-update-to-0_3_1.js'),('20150915153700-change-notes-title-to-text.js'),('20160112220142-note-add-lastchange.js'),('20160420180355-note-add-alias.js'),('20160515114000-user-add-tokens.js'),('20160607060246-support-revision.js'),('20160703062241-support-authorship.js'),('20161009040430-support-delete-note.js'),('20161201050312-support-email-signin.js'),('20171009121200-longtext-for-mysql.js'),('20180209120907-longtext-of-authorship.js'),('20180306150303-fix-enum.js'),('20180326103000-use-text-in-tokens.js'),('20180525153000-user-add-delete-token.js');
/*!40000 ALTER TABLE `SequelizeMeta` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `Temp`
--

DROP TABLE IF EXISTS `Temp`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Temp` (
`id` varchar(255) NOT NULL,
`date` text,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `Temp`
--

LOCK TABLES `Temp` WRITE;
/*!40000 ALTER TABLE `Temp` DISABLE KEYS */;
/*!40000 ALTER TABLE `Temp` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `Users`
--

DROP TABLE IF EXISTS `Users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Users` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`profileid` varchar(255) DEFAULT NULL,
`profile` text,
`history` text,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
`accessToken` text,
`refreshToken` text,
`email` text,
`password` text,
`deleteToken` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `profileid` (`profileid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `Users`
--

LOCK TABLES `Users` WRITE;
/*!40000 ALTER TABLE `Users` DISABLE KEYS */;
/*!40000 ALTER TABLE `Users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2021-01-17 16:45:34

0 comments on commit 05990da

Please sign in to comment.