Merge branch 'master' of gitlab.cip.ifi.lmu.de:jost/UniWorX
This commit is contained in:
commit
10608b6256
@ -1,13 +1,6 @@
|
|||||||
# After you've edited this file, remove the following line to allow
|
root: ..
|
||||||
# `yesod keter` to build your bundle.
|
|
||||||
user-edited: false
|
|
||||||
|
|
||||||
# A Keter app is composed of 1 or more stanzas. The main stanza will define our
|
|
||||||
# web application. See the Keter documentation for more information on
|
|
||||||
# available stanzas.
|
|
||||||
stanzas:
|
stanzas:
|
||||||
|
|
||||||
# Your Yesod application.
|
|
||||||
- type: webapp
|
- type: webapp
|
||||||
|
|
||||||
# Name of your executable. You are unlikely to need to change this.
|
# Name of your executable. You are unlikely to need to change this.
|
||||||
@ -22,49 +15,28 @@ stanzas:
|
|||||||
args: []
|
args: []
|
||||||
|
|
||||||
hosts:
|
hosts:
|
||||||
# You can specify one or more hostnames for your application to respond
|
- testworx.tcs.ifi.lmu.de
|
||||||
# to. The primary hostname will be used for generating your application
|
|
||||||
# root.
|
|
||||||
- www.uniworx.com
|
|
||||||
|
|
||||||
# Enable to force Keter to redirect to https
|
ssl: true
|
||||||
# Can be added to any stanza
|
|
||||||
requires-secure: false
|
|
||||||
|
|
||||||
# Static files.
|
forward-env:
|
||||||
- type: static-files
|
- LDAPURI
|
||||||
hosts:
|
- LDAPDN
|
||||||
- static.uniworx.com
|
- LDAPPW
|
||||||
root: ../static
|
- LDAPBN
|
||||||
|
- DUMMY_LOGIN
|
||||||
# Uncomment to turn on directory listings.
|
- DETAILED_LOGGING
|
||||||
# directory-listing: true
|
- LOG_ALL
|
||||||
|
|
||||||
# Redirect plain domain name to www.
|
|
||||||
- type: redirect
|
|
||||||
|
|
||||||
hosts:
|
|
||||||
- uniworx.com
|
|
||||||
actions:
|
|
||||||
- host: www.uniworx.com
|
|
||||||
# secure: false
|
|
||||||
# port: 80
|
|
||||||
|
|
||||||
# Uncomment to switch to a non-permanent redirect.
|
|
||||||
# status: 303
|
|
||||||
|
|
||||||
# Use the following to automatically copy your bundle upon creation via `yesod
|
# Use the following to automatically copy your bundle upon creation via `yesod
|
||||||
# keter`. Uses `scp` internally, so you can set it to a remote destination
|
# keter`. Uses `scp` internally, so you can set it to a remote destination
|
||||||
# copy-to: user@host:/opt/keter/incoming/
|
# copy-to: user@host:/opt/keter/incoming/
|
||||||
|
copy-to: keter@testworx.tcs.ifi.lmu.de:/opt/keter/incoming/
|
||||||
# You can pass arguments to `scp` used above. This example limits bandwidth to
|
copy-to-args:
|
||||||
# 1024 Kbit/s and uses port 2222 instead of the default 22
|
- "-P 30363"
|
||||||
# copy-to-args:
|
|
||||||
# - "-l 1024"
|
|
||||||
# - "-P 2222"
|
|
||||||
|
|
||||||
# If you would like to have Keter automatically create a PostgreSQL database
|
# If you would like to have Keter automatically create a PostgreSQL database
|
||||||
# and set appropriate environment variables for it to be discovered, uncomment
|
# and set appropriate environment variables for it to be discovered, uncomment
|
||||||
# the following line.
|
# the following line.
|
||||||
# plugins:
|
plugins:
|
||||||
# postgres: true
|
postgres: true
|
||||||
|
|||||||
@ -8,17 +8,17 @@ ip-from-header: "_env:IP_FROM_HEADER:false"
|
|||||||
|
|
||||||
# Default behavior: determine the application root from the request headers.
|
# Default behavior: determine the application root from the request headers.
|
||||||
# Uncomment to set an explicit approot
|
# Uncomment to set an explicit approot
|
||||||
#approot: "_env:APPROOT:http://localhost:3000"
|
approot: "_env:APPROOT:http://localhost:3000"
|
||||||
|
|
||||||
# Optional values with the following production defaults.
|
# Optional values with the following production defaults.
|
||||||
# In development, they default to the inverse.
|
# In development, they default to the inverse.
|
||||||
#
|
#
|
||||||
# detailed-logging: false
|
detailed-logging: "_env:DETAILED_LOGGING:false"
|
||||||
# should-log-all: false
|
should-log-all: "_env:LOG_ALL:false"
|
||||||
# reload-templates: false
|
# reload-templates: false
|
||||||
# mutable-static: false
|
# mutable-static: false
|
||||||
# skip-combining: false
|
# skip-combining: false
|
||||||
# auth-dummy-login : false
|
auth-dummy-login: "_env:DUMMY_LOGIN:false"
|
||||||
|
|
||||||
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:PGPASS:'123'")
|
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:PGPASS:'123'")
|
||||||
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
||||||
@ -32,6 +32,12 @@ database:
|
|||||||
database: "_env:PGDATABASE:uniworx"
|
database: "_env:PGDATABASE:uniworx"
|
||||||
poolsize: "_env:PGPOOLSIZE:10"
|
poolsize: "_env:PGPOOLSIZE:10"
|
||||||
|
|
||||||
|
ldap:
|
||||||
|
uri: "_env:LDAPURI:ldap://localhost:389"
|
||||||
|
dn: "_env:LDAPDN:uniworx"
|
||||||
|
password: "_env:LDAPPW:"
|
||||||
|
basename: "_env:LDAPBN:"
|
||||||
|
|
||||||
cryptoid-keyfile: "_env:CRYPTOID_KEYFILE:cryptoid_key.bf"
|
cryptoid-keyfile: "_env:CRYPTOID_KEYFILE:cryptoid_key.bf"
|
||||||
|
|
||||||
copyright: Insert copyright statement here
|
copyright: Insert copyright statement here
|
||||||
|
|||||||
6
docker/Dockerfile
Normal file
6
docker/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
FROM fpco/stack-build:lts-9.3
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install libldap2-dev libsasl2-dev
|
||||||
2
models
2
models
@ -1,7 +1,7 @@
|
|||||||
User
|
User
|
||||||
plugin Text
|
plugin Text
|
||||||
ident Text
|
ident Text
|
||||||
matrikelnummer Text
|
matrikelnummer Text Maybe
|
||||||
UniqueAuthentication plugin ident
|
UniqueAuthentication plugin ident
|
||||||
Term json
|
Term json
|
||||||
name TermIdentifier
|
name TermIdentifier
|
||||||
|
|||||||
@ -72,6 +72,8 @@ dependencies:
|
|||||||
- generic-deriving
|
- generic-deriving
|
||||||
- blaze-html
|
- blaze-html
|
||||||
- conduit-resumablesink >=0.2
|
- conduit-resumablesink >=0.2
|
||||||
|
- yesod-auth-ldap
|
||||||
|
- LDAP
|
||||||
|
|
||||||
# The library contains all of our application code. The executable
|
# The library contains all of our application code. The executable
|
||||||
# defined below is just a thin wrapper.
|
# defined below is just a thin wrapper.
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
{-# LANGUAGE ViewPatterns #-}
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
{-# LANGUAGE PatternGuards #-}
|
{-# LANGUAGE PatternGuards #-}
|
||||||
|
|
||||||
module Foundation where
|
module Foundation where
|
||||||
@ -16,9 +17,13 @@ import Text.Hamlet (hamletFile)
|
|||||||
import Text.Jasmine (minifym)
|
import Text.Jasmine (minifym)
|
||||||
|
|
||||||
-- Used only when in "auth-dummy-login" setting is enabled.
|
-- Used only when in "auth-dummy-login" setting is enabled.
|
||||||
|
import Yesod.Auth.Message
|
||||||
import Yesod.Auth.Dummy
|
import Yesod.Auth.Dummy
|
||||||
|
import Yesod.Auth.LDAP
|
||||||
|
|
||||||
|
import LDAP.Data (LDAPScope(..))
|
||||||
|
import LDAP.Search (LDAPEntry(..))
|
||||||
|
|
||||||
import Yesod.Auth.OpenId (authOpenId, IdentifierType (Claimed))
|
|
||||||
import Yesod.Default.Util (addStaticContentExternal)
|
import Yesod.Default.Util (addStaticContentExternal)
|
||||||
import Yesod.Core.Types (Logger)
|
import Yesod.Core.Types (Logger)
|
||||||
import qualified Yesod.Core.Unsafe as Unsafe
|
import qualified Yesod.Core.Unsafe as Unsafe
|
||||||
@ -279,29 +284,54 @@ instance YesodAuth UniWorX where
|
|||||||
-- Override the above two destinations when a Referer: header is present
|
-- Override the above two destinations when a Referer: header is present
|
||||||
redirectToReferer _ = True
|
redirectToReferer _ = True
|
||||||
|
|
||||||
authenticate Creds{..} = runDB $ do
|
authenticate creds@(Creds{..}) = runDB $ do
|
||||||
let (plugin, ident)
|
let (userPlugin, userIdent)
|
||||||
| credsPlugin == "dummy"
|
| isDummy
|
||||||
, [dummyPlugin, dummyIdent] <- Text.splitOn ":" credsIdent
|
, [dummyPlugin, dummyIdent] <- Text.splitOn ":" credsIdent
|
||||||
= (dummyPlugin, dummyIdent)
|
= (dummyPlugin, dummyIdent)
|
||||||
| otherwise
|
| otherwise
|
||||||
= (credsPlugin, credsIdent)
|
= (credsPlugin, credsIdent)
|
||||||
x <- getBy $ UniqueAuthentication plugin ident
|
isDummy = credsPlugin == "dummy"
|
||||||
case x of
|
uAuth = UniqueAuthentication userPlugin userIdent
|
||||||
Just (Entity uid _) -> return $ Authenticated uid
|
|
||||||
Nothing -> Authenticated <$> insert User
|
$logDebugS "auth" $ tshow ((userPlugin, userIdent), creds)
|
||||||
{ userPlugin = plugin
|
|
||||||
, userIdent = ident
|
case isDummy of
|
||||||
, userMatrikelnummer = "DummyMatrikel"
|
True ->
|
||||||
}
|
maybe (UserError $ IdentifierNotFound credsIdent) (Authenticated . entityKey) <$> getBy uAuth
|
||||||
|
False -> do
|
||||||
|
let
|
||||||
|
userMatrikelnummer = lookup "LMU-Stud-Matrikelnummer" credsExtra
|
||||||
|
|
||||||
|
newUser = User{..}
|
||||||
|
userUpdate = [ UserMatrikelnummer =. userMatrikelnummer
|
||||||
|
]
|
||||||
|
Authenticated . entityKey <$> upsertBy uAuth newUser userUpdate
|
||||||
|
|
||||||
-- You can add other plugins like Google Email, email or OAuth here
|
-- You can add other plugins like Google Email, email or OAuth here
|
||||||
authPlugins app = [authOpenId Claimed []] ++ extraAuthPlugins
|
authPlugins app = [genericAuthLDAP $ ldapConfig app] ++ extraAuthPlugins
|
||||||
-- Enable authDummy login if enabled.
|
-- Enable authDummy login if enabled.
|
||||||
where extraAuthPlugins = [authDummy | appAuthDummyLogin $ appSettings app]
|
where extraAuthPlugins = [authDummy | appAuthDummyLogin $ appSettings app]
|
||||||
|
|
||||||
authHttpManager = getHttpManager
|
authHttpManager = getHttpManager
|
||||||
|
|
||||||
|
ldapConfig :: UniWorX -> LDAPConfig
|
||||||
|
ldapConfig app@(appSettings -> settings) = LDAPConfig
|
||||||
|
{ usernameFilter = \u -> principalName <> "=" <> u
|
||||||
|
, identifierModifier
|
||||||
|
, ldapUri = appLDAPURI settings
|
||||||
|
, initDN = appLDAPDN settings
|
||||||
|
, initPass = appLDAPPw settings
|
||||||
|
, baseDN = appLDAPBaseName settings
|
||||||
|
, ldapScope = LdapScopeSubtree
|
||||||
|
}
|
||||||
|
where
|
||||||
|
principalName :: IsString a => a
|
||||||
|
principalName = "userPrincipalName"
|
||||||
|
identifierModifier _ entry = case lookup principalName $ leattrs entry of
|
||||||
|
Just [n] -> Text.pack n
|
||||||
|
_ -> error "Could not determine user principal name"
|
||||||
|
|
||||||
-- | Access function to determine if a user is logged in.
|
-- | Access function to determine if a user is logged in.
|
||||||
isAuthenticated :: Handler AuthResult
|
isAuthenticated :: Handler AuthResult
|
||||||
isAuthenticated = do
|
isAuthenticated = do
|
||||||
|
|||||||
@ -43,6 +43,11 @@ data AppSettings = AppSettings
|
|||||||
-- ^ Get the IP address from the header when logging. Useful when sitting
|
-- ^ Get the IP address from the header when logging. Useful when sitting
|
||||||
-- behind a reverse proxy.
|
-- behind a reverse proxy.
|
||||||
|
|
||||||
|
, appLDAPURI :: String
|
||||||
|
, appLDAPDN :: String
|
||||||
|
, appLDAPPw :: String
|
||||||
|
, appLDAPBaseName :: Maybe String
|
||||||
|
|
||||||
, appDetailedRequestLogging :: Bool
|
, appDetailedRequestLogging :: Bool
|
||||||
-- ^ Use detailed request logging system
|
-- ^ Use detailed request logging system
|
||||||
, appShouldLogAll :: Bool
|
, appShouldLogAll :: Bool
|
||||||
@ -80,6 +85,9 @@ instance FromJSON AppSettings where
|
|||||||
appPort <- o .: "port"
|
appPort <- o .: "port"
|
||||||
appIpFromHeader <- o .: "ip-from-header"
|
appIpFromHeader <- o .: "ip-from-header"
|
||||||
|
|
||||||
|
( appLDAPURI, appLDAPDN, appLDAPPw, appLDAPBaseName )
|
||||||
|
<- (=<< o .: "ldap") . withObject "LDAP" $ \obj -> (,,,) <$> obj .: "uri" <*> obj .: "dn" <*> obj .: "password" <*> obj .:? "basename"
|
||||||
|
|
||||||
appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev
|
appDetailedRequestLogging <- o .:? "detailed-logging" .!= defaultDev
|
||||||
appShouldLogAll <- o .:? "should-log-all" .!= defaultDev
|
appShouldLogAll <- o .:? "should-log-all" .!= defaultDev
|
||||||
appReloadTemplates <- o .:? "reload-templates" .!= defaultDev
|
appReloadTemplates <- o .:? "reload-templates" .!= defaultDev
|
||||||
|
|||||||
14
stack.yaml
14
stack.yaml
@ -1,5 +1,9 @@
|
|||||||
flags: {}
|
flags: {}
|
||||||
|
docker:
|
||||||
|
enable: true
|
||||||
|
image: uniworx
|
||||||
nix:
|
nix:
|
||||||
|
enable: false
|
||||||
packages: []
|
packages: []
|
||||||
pure: false
|
pure: false
|
||||||
shell-file: ./stack.nix
|
shell-file: ./stack.nix
|
||||||
@ -10,6 +14,14 @@ packages:
|
|||||||
git: https://github.com/pngwjpgh/zip-stream.git
|
git: https://github.com/pngwjpgh/zip-stream.git
|
||||||
commit: 9272bbed000928d500febad1cdc98d1da29d399e
|
commit: 9272bbed000928d500febad1cdc98d1da29d399e
|
||||||
extra-dep: true
|
extra-dep: true
|
||||||
|
- location:
|
||||||
|
git: https://github.com/mlitchard/yesod-auth-ldap.git
|
||||||
|
commit: 69e08ef687ab96df3352ff4267562135453c6f02
|
||||||
|
extra-dep: true
|
||||||
|
- location:
|
||||||
|
git: https://github.com/mlitchard/authenticate-ldap.git
|
||||||
|
commit: cc2770024766a8fa29d3086688df60aaf65fb954
|
||||||
|
extra-dep: true
|
||||||
extra-deps:
|
extra-deps:
|
||||||
- colonnade-1.1.1
|
- colonnade-1.1.1
|
||||||
- yesod-colonnade-1.1.0
|
- yesod-colonnade-1.1.0
|
||||||
@ -22,4 +34,6 @@ extra-deps:
|
|||||||
|
|
||||||
- encoding-0.8.2
|
- encoding-0.8.2
|
||||||
- regex-compat-0.93.1
|
- regex-compat-0.93.1
|
||||||
|
|
||||||
|
- LDAP-0.6.11
|
||||||
resolver: lts-9.3
|
resolver: lts-9.3
|
||||||
|
|||||||
Reference in New Issue
Block a user