summaryrefslogtreecommitdiff
path: root/src/Propellor
diff options
context:
space:
mode:
Diffstat (limited to 'src/Propellor')
-rw-r--r--src/Propellor/Property/Mysql.hs82
1 files changed, 38 insertions, 44 deletions
diff --git a/src/Propellor/Property/Mysql.hs b/src/Propellor/Property/Mysql.hs
index 77775889..f7639a29 100644
--- a/src/Propellor/Property/Mysql.hs
+++ b/src/Propellor/Property/Mysql.hs
@@ -21,6 +21,7 @@ import Propellor.Base
import Data.List
import qualified Propellor.Property.Apt as Apt
+-- | A database is defined by its name.
newtype Database = Database String
data Privilege
@@ -41,48 +42,30 @@ data Privilege
| AlterRoutine
| Event
| Trigger
- deriving (Eq, Ord)
+ deriving (Eq, Ord, Enum)
-instance Show Privilege where
- show Select = "SELECT"
- show Insert = "INSERT"
- show Update = "UPDATE"
- show Delete = "DELETE"
- show Create = "CREATE"
- show Drop = "DROP"
- show Index = "INDEX"
- show Alter = "ALTER"
- show CreateTemporaryTables = "CREATE TEMPORARY TABLES"
- show LockTables = "LOCK TABLES"
- show Execute = "EXECUTE"
- show CreateView = "CREATE VIEW"
- show ShowView = "SHOW VIEW"
- show CreateRoutine = "CREATE ROUTINE"
- show AlterRoutine = "ALTER ROUTINE"
- show Event = "EVENT"
- show Trigger = "TRIGGER"
+sqlPrivilege :: Privilege -> String
+sqlPrivilege Select = "SELECT"
+sqlPrivilege Insert = "INSERT"
+sqlPrivilege Update = "UPDATE"
+sqlPrivilege Delete = "DELETE"
+sqlPrivilege Create = "CREATE"
+sqlPrivilege Drop = "DROP"
+sqlPrivilege Index = "INDEX"
+sqlPrivilege Alter = "ALTER"
+sqlPrivilege CreateTemporaryTables = "CREATE TEMPORARY TABLES"
+sqlPrivilege LockTables = "LOCK TABLES"
+sqlPrivilege Execute = "EXECUTE"
+sqlPrivilege CreateView = "CREATE VIEW"
+sqlPrivilege ShowView = "SHOW VIEW"
+sqlPrivilege CreateRoutine = "CREATE ROUTINE"
+sqlPrivilege AlterRoutine = "ALTER ROUTINE"
+sqlPrivilege Event = "EVENT"
+sqlPrivilege Trigger = "TRIGGER"
-- | All privileges
allPrivileges :: [Privilege]
-allPrivileges =
- [ Select
- , Insert
- , Update
- , Delete
- , Create
- , Drop
- , Index
- , Alter
- , CreateTemporaryTables
- , LockTables
- , Execute
- , CreateView
- , ShowView
- , CreateRoutine
- , AlterRoutine
- , Event
- , Trigger
- ]
+allPrivileges = [Select .. Trigger]
-- | Basic privileges needed to use a classic database already created.
basicPrivileges :: [Privilege]
@@ -156,7 +139,8 @@ databaseExists (Database dbname) =
dbPresent :: IO Bool
dbPresent = (== trueResult) <$> readProcess "mysql" ["-BNre", sql]
where
- sql = "show databases like '" ++ dbname ++ "'"
+ sql = "SHOW DATABASES LIKE " ++ qdbname
+ qdbname = sqlQuote '\'' dbname
trueResult = dbname ++ "\n"
-- Create an user and make sure he has grants on the specific database but no
@@ -183,7 +167,7 @@ userGrantedOnDatabase user@(User username) (Database dbname) privs context =
++ "GRANT " ++ privList ++ " ON " ++ privLevel
++ " TO " ++ quser ++ "\n"
-- Privilege level for database access.
- privLevel = "`" ++ dbname ++ "`.*"
+ privLevel = (sqlQuote '`' dbname) ++ ".*"
-- Create an user and make sure he has global grants but no other grant.
userGranted
@@ -266,16 +250,26 @@ userGranted' (User username) privs context setupDesc setupSql userGrants =
(Just writer) Nothing
where
writer h = hPutStr h sql
- sql = "select password('" ++ password ++ "')"
+ sql = "SELECT PASSWORD(" ++ qpassword ++ ")"
+ qpassword = sqlQuote '\'' password
-- Request current user grants from MySQL.
getUserGrants :: IO String
getUserGrants =
catchDefaultIO "" $ readProcess "mysql" ["-BNre", sql]
where
- sql = "show grants for " ++ quser
+ sql = "SHOW GRANTS FOR " ++ quser
-- Privilege list as output by MySQL.
- privList = intercalate ", " $ map show $ nub $ sort privs
+ privList = intercalate ", " $ map sqlPrivilege $ nub $ sort privs
-- Qualified user name.
- quser = "'" ++ username ++ "'@'localhost'"
+ quser = (sqlQuote '\'' username) ++ "@'localhost'"
+
+-- | Quote a string using the given quote character.
+sqlQuote :: Char -> String -> String
+sqlQuote quote s =
+ [quote] ++ (concatMap escape s) ++ [quote]
+ where
+ escape c
+ | c == quote = [quote, quote]
+ | otherwise = [c]