Skip to content

Commit

Permalink
Link up read settings
Browse files Browse the repository at this point in the history
  • Loading branch information
NHAS committed Feb 7, 2024
1 parent a4adb97 commit b07450a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 76 deletions.
50 changes: 49 additions & 1 deletion internal/data/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,19 @@ type Settings struct {
Lockout int
Issuer string
Domain string
WireguardConfigFilename string
SessionInactivityTimeoutMinutes int
MaxSessionLifetimeMinutes int
HelpMail string
DNS []string

DefaultMFAMethod string
EnabledMFAMethods []string

OidcDetails OIDC
PamDetails PAM

CheckUpdates bool
}

func GetAllSettings() (s Settings, err error) {
Expand All @@ -281,7 +290,13 @@ func GetAllSettings() (s Settings, err error) {
clientv3.OpGet(LockoutKey),
clientv3.OpGet(dnsKey),
clientv3.OpGet(IssuerKey),
clientv3.OpGet(DomainKey)).Commit()
clientv3.OpGet(DomainKey),
clientv3.OpGet(DefaultMFAMethodKey),
clientv3.OpGet(MethodsEnabledKey),
clientv3.OpGet(checkUpdatesKey),
clientv3.OpGet(OidcDetailsKey),
clientv3.OpGet(PamDetailsKey),
clientv3.OpGet(defaultWGFileNameKey)).Commit()
if err != nil {
return s, err
}
Expand Down Expand Up @@ -331,6 +346,39 @@ func GetAllSettings() (s Settings, err error) {
s.Domain = string(response.Responses[7].GetResponseRange().Kvs[0].Value)
}

if response.Responses[8].GetResponseRange().Count == 1 {
s.DefaultMFAMethod = string(response.Responses[8].GetResponseRange().Kvs[0].Value)
}

if response.Responses[9].GetResponseRange().Count == 1 {
err := json.Unmarshal(response.Responses[9].GetResponseRange().Kvs[0].Value, &s.EnabledMFAMethods)
if err != nil {
return s, err
}
}

if response.Responses[10].GetResponseRange().Count == 1 {
s.CheckUpdates = string(response.Responses[10].GetResponseRange().Kvs[0].Value) == "true"
}

if response.Responses[11].GetResponseRange().Count == 1 {
err := json.Unmarshal(response.Responses[11].GetResponseRange().Kvs[0].Value, &s.OidcDetails)
if err != nil {
return s, err
}
}

if response.Responses[12].GetResponseRange().Count == 1 {
err := json.Unmarshal(response.Responses[12].GetResponseRange().Kvs[0].Value, &s.PamDetails)
if err != nil {
return s, err
}
}

if response.Responses[13].GetResponseRange().Count == 1 {
s.WireguardConfigFilename = string(response.Responses[13].GetResponseRange().Kvs[0].Value)
}

return
}

Expand Down
17 changes: 17 additions & 0 deletions internal/webserver/authenticators/authenticators.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,23 @@ func GetAllEnabledMethods() (r []Authenticator) {
return
}

func GetAllAvaliableMethods() (r []Authenticator) {
lck.RLock()
defer lck.RUnlock()

order := []string{}
for k := range allMfa {
order = append(order, string(k))
}

sort.Strings(order)

for _, m := range order {
r = append(r, allMfa[types.MFA(m)])
}
return
}

func AddMFARoutes(mux *http.ServeMux) error {
for method, handler := range allMfa {
mux.HandleFunc("/authorise/"+string(method)+"/", checkEnabled(handler, handler.AuthorisationAPI))
Expand Down
23 changes: 9 additions & 14 deletions ui/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"encoding/json"
"log"
"net/http"
"strings"

"github.com/NHAS/wag/internal/data"
"github.com/NHAS/wag/internal/webserver/authenticators"
)

func adminUsersUI(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -87,7 +87,7 @@ func clusteringUI(w http.ResponseWriter, r *http.Request) {
ClusterState: clusterState,
}

err := renderDefaults(w, r, d, "management/clustering.html")
err := renderDefaults(w, r, d, "settings/clustering.html")

if err != nil {
log.Println("unable to render clustering page: ", err)
Expand Down Expand Up @@ -119,7 +119,11 @@ func generalSettingsUI(w http.ResponseWriter, r *http.Request) {
return
}

d := GeneralSettings{
d := struct {
Page Page
Settings data.Settings
MFAMethods []authenticators.Authenticator
}{
Page: Page{
Update: getUpdate(),
Description: "Wag settings",
Expand All @@ -130,17 +134,8 @@ func generalSettingsUI(w http.ResponseWriter, r *http.Request) {
ClusterState: clusterState,
},

ExternalAddress: datastoreSettings.ExternalAddress,
Lockout: datastoreSettings.Lockout,
Issuer: datastoreSettings.Issuer,
Domain: datastoreSettings.Domain,
InactivityTimeoutMinutes: datastoreSettings.SessionInactivityTimeoutMinutes,
SessionLifeTimeMinutes: datastoreSettings.MaxSessionLifetimeMinutes,
HelpMail: datastoreSettings.HelpMail,
DNS: strings.Join(datastoreSettings.DNS, "\n"),
TotpEnabled: true,
OidcEnabled: false,
WebauthnEnabled: false,
Settings: datastoreSettings,
MFAMethods: authenticators.GetAllAvaliableMethods(),
}

err = renderDefaults(w, r, d, "settings/general.html")
Expand Down
20 changes: 0 additions & 20 deletions ui/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,6 @@ type Dashboard struct {
LogItems []string
}

type GeneralSettings struct {
Page
OidcIdpURL string
OidcClientID string
OidcGroupsClaim string

Issuer string
Domain string

Lockout int
InactivityTimeoutMinutes int
SessionLifeTimeMinutes int

ExternalAddress string
HelpMail string
DNS string

OidcEnabled, WebauthnEnabled, TotpEnabled bool
}

type Login struct {
ErrorMessage string
}
Expand Down
File renamed without changes.
69 changes: 28 additions & 41 deletions ui/templates/settings/general.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,36 @@ <h6 class="m-0 font-weight-bold text-primary">General</h6>
<div class="form-group col-md-6">
<label for="inputHelpMail">Help Mail</label>
<input type="email" class="form-control" name="inputHelpMail" id="inputHelpMail"
value="{{.HelpMail}}">
value="{{.Settings.HelpMail}}">
</div>
<div class="form-group col-md-6">
<label for="inputWgAddress">External Wireguard Address</label>
<input type="text" class="form-control" name="inputWgAddress" id="inputWgAddress"
value="{{.ExternalAddress}}">
value="{{.Settings.ExternalAddress}}">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputConf">Wireguard Config Filename</label>
<input type="email" class="form-control" name="inputConfFileName" id="inputConf"
value="wg0.conf">
value="{{.Settings.WireguardConfigFilename}}">
</div>
<div class="form-group col-md-6">
<label for="inputVPNDomain">VPN Domain</label>
<input type="text" class="form-control" name="inputVPNDomain" id="inputVPNDomain"
value="http://vpn.test">
value="{{.Settings.Domain}}">
</div>
</div>

<div class="form-group">
<label for="dns">DNS</label>
<textarea class="form-control" id="dns" name="dns" rows="3">{{.DNS}}</textarea>
<textarea class="form-control" id="dns" name="dns" rows="3">{{.Settings.DNS}}</textarea>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="checkForUpdates" value="true"
id="checkUpdates">
id="checkUpdates" {{if .Settings.CheckUpdates}}checked{{end}}>
<label class="form-check-label" for="checkUpdates">
Check for Updates
</label>
Expand Down Expand Up @@ -76,92 +76,79 @@ <h6 class="m-0 font-weight-bold text-primary d-inline">Login</h6>
<div class="col-md-6">
<label for="inputSessionLife">Session Life Time (Minutes)</label>
<input type="number" class="form-control" id="inputSessionLife" name="inputSessionLife"
value="{{.SessionLifeTimeMinutes}}">
value="{{.Settings.SessionLifeTimeMinutes}}">
</div>
<div class="col-md-6">
<label for="inputInactivity">Inactivity Timeout (Minutes)</label>
<input type="number" class="form-control" id="inputInactivity" name="inputInactivity"
value="{{.InactivityTimeoutMinutes}}">
value="{{.Settings.InactivityTimeoutMinutes}}">
</div>
</div>

<div class="form-group mb-3">
<label for="numAttempts">Max Authentication Attempts</label>
<input type="number" class="form-control" id="numAttempts" name="numAttempts"
value="{{.Lockout}}">
value="{{.Settings.Lockout}}">
</div>

<!-- Add MFA Fields -->
<div class="form-group mb-3">
<label for="defaultMFA">Default MFA Method</label>
<select class="form-control" id="defaultMFA" name="defaultMFA">
<option value="sms">TOTP</option>
<option value="email">Webauthn</option>
<option value="app">OIDC (SSO)</option>
<option value="app">PAM</option>
{{range .Settings.EnabledMFAMethods}}
<option value="{{.}}" {{if eq . $.Settings.DefaultMFAMethod}}selected{{end}}>{{.}}</option>
{{end}}
</select>
</div>

<div class="form-group mb-3">
<label>Enabled MFA Methods</label>
<label>MFA Methods</label>
<div class="form-row mb-3">
<div class="col-md-6">
{{range $index, $method := .Settings.MFAMethods}}
<div class="col-md">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="sms" id="enableSMS"
name="enabledMethods[]">
<label class="form-check-label" for="enableSMS">TOTP</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="email" id="enableEmail"
name="enabledMethods[]">
<label class="form-check-label" for="enableEmail">Webauthn</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="app" id="enableApp"
name="enabledMethods[]">
<label class="form-check-label" for="enableApp">Single Sign On</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="app" id="enableApp"
name="enabledMethods[]">
<label class="form-check-label" for="enableApp">PAM</label>
<input class="form-check-input" type="checkbox" value="{{$method.Type}}"
name="{{$method.Type}}" {{if $method.Enabled}}checked{{done}}>
<label class="form-check-label" for="{{$method.Type}}">{{$method.Type}}</label>
</div>
</div>
{{end}}
</div>
</div>

<!-- Webauthn/TOTP Settings -->
<div class="form-group mb-3">
<label for="issuer">Issuer</label>
<input type="text" class="form-control" id="issuer" name="issuer" value="">
<input type="text" class="form-control" id="issuer" name="issuer" value="{{.Settings.Issuer}}">
</div>

<!-- OIDC Settings -->
<div class="form-group mb-3">
<label for="oidcIssuerURL">OIDC Identity Provider</label>
<input type="text" class="form-control" id="oidcIssuerURL" name="oidcIssuerURL" value="">
<input type="text" class="form-control" id="oidcIssuerURL" name="oidcIssuerURL"
value="{{.Settings.OidcDetails.IssuerURL}}">
</div>
<div class="form-group mb-3">
<label for="oidcClientSecret">OIDC Client Secret</label>
<input type="password" class="form-control" id="oidcClientSecret" name="oidcClientSecret"
value="">
value="***********">
</div>
<div class="form-group mb-3">
<label for="oidcClientID">OIDC Client ID</label>
<input type="text" class="form-control" id="oidcClientID" name="oidcClientID" value="">
<input type="text" class="form-control" id="oidcClientID" name="oidcClientID"
value="{{.Settings.OidcDetails.ClientID}}">
</div>
<div class="form-group mb-3">
<label for="oidcGroupsClaimName">OIDC Groups Claim Name</label>
<input type="text" class="form-control" id="oidcGroupsClaimName" name="oidcGroupsClaimName"
value="">
value="{{.Settings.OidcDetails.GroupsClaimName}}">
</div>

<!-- PAM Settings -->
<div class="form-group">
<label for="pamServiceName">PAM Service Name</label>
<input type="text" class="form-control" id="pamServiceName" name="pamServiceName" value="">
<input type="text" class="form-control" id="pamServiceName" name="pamServiceName"
value="{{.Settings.PamDetails.ServiceName}}">
</div>

<div id="loginSettingsIssue" role="alert" style="display:none"></div>
Expand Down

0 comments on commit b07450a

Please sign in to comment.