This repository has been archived by the owner on Jul 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 83
settings for enx #437
Merged
Merged
settings for enx #437
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -21,6 +21,21 @@ <h1>Realm settings</h1> | |||||
Find or edit the settings for <strong>{{$realm.Name}}</strong> below. | ||||||
</p> | ||||||
|
||||||
{{if not $realm.EnableENExpress}} | ||||||
<div class="card mb-3"> | ||||||
<div class="card-header"> | ||||||
ENX - Exposure Notifications Express | ||||||
</div> | ||||||
<div class="card-body"> | ||||||
<form method="POST" action="/realm/settings/enable-express"> | ||||||
{{ .csrfField }} | ||||||
<a href="#" class="btn btn-primary btn-block" data-confirm="Are you sure you want to enable EN Express? You should only do this if you have confirmed participation with Apple and Google." data-submit-form>Enable EN Express</a> | ||||||
</form> | ||||||
</div> | ||||||
</div> | ||||||
{{end}} | ||||||
|
||||||
|
||||||
<form method="POST" action="/realm/settings/save"> | ||||||
{{ .csrfField }} | ||||||
|
||||||
|
@@ -61,6 +76,7 @@ <h1>Realm settings</h1> | |||||
<div class="form-group row mb-0"> | ||||||
<label class="col-sm-3">Allowed tests:</label> | ||||||
<div class="col-sm-9"> | ||||||
{{if not $realm.EnableENExpress}} | ||||||
<div class="form-group mb-0"> | ||||||
<div class="form-check"> | ||||||
<input class="form-check-input" type="radio" name="allowedTestTypes" id="negative" value="{{$testTypes.negative}}"{{if eq $realm.AllowedTestTypes $testTypes.negative}} checked{{end}}/> | ||||||
|
@@ -87,6 +103,7 @@ <h1>Realm settings</h1> | |||||
</label> | ||||||
</div> | ||||||
</div> | ||||||
{{end}} | ||||||
|
||||||
<div class="form-group"> | ||||||
<div class="form-check"> | ||||||
|
@@ -96,6 +113,10 @@ <h1>Realm settings</h1> | |||||
<small class="form-text text-muted"> | ||||||
Only permit confirmed positive tests from an official | ||||||
testing source. | ||||||
{{if $realm.EnableENExpress}} <br/> | ||||||
You are enrolled in EN Express which only supports the sharing of | ||||||
positive tests. | ||||||
{{end}} | ||||||
</small> | ||||||
</label> | ||||||
</div> | ||||||
|
@@ -113,6 +134,9 @@ <h1>Realm settings</h1> | |||||
<div class="form-group row"> | ||||||
<label for="codeLength" class="col-sm-3">Short code characters:</label> | ||||||
<div class="col-sm-9"> | ||||||
{{if $realm.EnableENExpress}} | ||||||
<input class="form-control{{if $realm.ErrorsFor "codeLength"}} is-invalid{{end}}" name="codeLength" id="codeLength" type="text" value="{{$realm.CodeLength}}" readonly /> | ||||||
{{else}} | ||||||
<select class="form-control{{if $realm.ErrorsFor "codeLength"}} is-invalid{{end}}" name="codeLength" id="codeLength"> | ||||||
{{range $cl := .shortCodeLengths}} | ||||||
<option value="{{$cl}}" {{if (eq $cl $realm.CodeLength)}}selected{{end}}>{{$cl}}</option> | ||||||
|
@@ -122,55 +146,68 @@ <h1>Realm settings</h1> | |||||
The short verification code is intended to be dictated over the phone to the | ||||||
person and is <code>6</code>, <code>7</code>, or <code>8</code> digits in length. | ||||||
</small> | ||||||
{{end}} | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div class="form-group row"> | ||||||
<label for="codeLength" class="col-sm-3">Code expires after:</label> | ||||||
<div class="col-sm-8"> | ||||||
<select class="form-control{{if $realm.ErrorsFor "CodeDurationSeconds"}} is-invalid{{end}}" name="codeDuration" id="codeDuration"> | ||||||
{{$current := $realm.GetCodeDurationMinutes}} | ||||||
{{range $scm := .shortCodeMinutes}} | ||||||
<option value="{{$scm}}" {{if (eq $scm $current)}}selected{{end}}>{{$scm}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
<small class="form-text text-muted"> | ||||||
The short code can be valid from anywhere between <code>5</code> and <code>60</code> | ||||||
minutes. If you are using SMS deeplinks, it is recommended to keep this duration | ||||||
short and let the long code be valid for a longer period (up to <code>24</code> hours). | ||||||
</small> | ||||||
{{if $realm.EnableENExpress}} | ||||||
<input class="form-control{{if $realm.ErrorsFor "CodeDurationSeconds"}} is-invalid{{end}}" name="codeDuration" id="codeDuration" type="text" value="{{$realm.GetCodeDurationMinutes}}" readonly /> | ||||||
{{else}} | ||||||
<select class="form-control{{if $realm.ErrorsFor "CodeDurationSeconds"}} is-invalid{{end}}" name="codeDuration" id="codeDuration"> | ||||||
{{$current := $realm.GetCodeDurationMinutes}} | ||||||
{{range $scm := .shortCodeMinutes}} | ||||||
<option value="{{$scm}}" {{if (eq $scm $current)}}selected{{end}}>{{$scm}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
<small class="form-text text-muted"> | ||||||
The short code can be valid from anywhere between <code>5</code> and <code>60</code> | ||||||
minutes. If you are using SMS deeplinks, it is recommended to keep this duration | ||||||
short and let the long code be valid for a longer period (up to <code>24</code> hours). | ||||||
</small> | ||||||
{{end}} | ||||||
</div> | ||||||
<div class="col-sm-1">minutes</div> | ||||||
</div> | ||||||
|
||||||
<div class="form-group row"> | ||||||
<label for="codeLength" class="col-sm-3">Long code characters:</label> | ||||||
<div class="col-sm-9"> | ||||||
<select class="form-control{{if $realm.ErrorsFor "longCodeLength"}} is-invalid{{end}}" name="longCodeLength" id="longCodeLength"> | ||||||
{{range $cl := .longCodeLengths}} | ||||||
<option value="{{$cl}}" {{if (eq $cl $realm.LongCodeLength)}}selected{{end}}>{{$cl}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
{{if $realm.EnableENExpress}} | ||||||
<input class="form-control{{if $realm.ErrorsFor "longCodeLength"}} is-invalid{{end}}" name="longCodeLength" id="longCodeLength" type="text" value="{{$realm.LongCodeLength}}" readonly /> | ||||||
{{else}} | ||||||
<select class="form-control{{if $realm.ErrorsFor "longCodeLength"}} is-invalid{{end}}" name="longCodeLength" id="longCodeLength"> | ||||||
{{range $cl := .longCodeLengths}} | ||||||
<option value="{{$cl}}" {{if (eq $cl $realm.LongCodeLength)}}selected{{end}}>{{$cl}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
{{end}} | ||||||
<small class="form-text text-muted"> | ||||||
The 'long' verification code is only delivered over SMS, is more complex with <code>12</code> - | ||||||
The 'long' verification code is only delivered over SMS{{if not $realm.EnableENExpress}}, is more complex with <code>12</code> - | ||||||
<code>16</code> alphanumeric characters, and is never shown to a human. It is recommended | ||||||
to leave this at the default of <code>16</code> digits. | ||||||
</small> | ||||||
to leave this at the default of <code>16</code> digits{{end}}. | ||||||
</small> | ||||||
</div> | ||||||
</div> | ||||||
|
||||||
<div class="form-group row"> | ||||||
<label for="codeLength" class="col-sm-3">Long code expires after:</label> | ||||||
<div class="col-sm-8"> | ||||||
<select class="form-control{{if $realm.ErrorsFor "LongCodeDurationSeconds"}} is-invalid{{end}}" name="longCodeDuration" id="longCodeDuration"> | ||||||
{{$current := $realm.GetLongCodeDurationHours}} | ||||||
{{range $lch := .longCodeHours}} | ||||||
<option value="{{$lch}}" {{if (eq $lch $current)}}selected{{end}}>{{$lch}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
<small class="form-text text-muted"> | ||||||
The long code can be valid between <code>1</code> and <code>24</code> hours. | ||||||
</small> | ||||||
{{if $realm.EnableENExpress}} | ||||||
<input class="form-control{{if $realm.ErrorsFor "LongCodeDurationSeconds"}} is-invalid{{end}}" name="longCodeDuration" id="longCodeDuration" type="text" value="{{$realm.GetLongCodeDurationHours}}" readonly /> | ||||||
{{else}} | ||||||
<select class="form-control{{if $realm.ErrorsFor "LongCodeDurationSeconds"}} is-invalid{{end}}" name="longCodeDuration" id="longCodeDuration"> | ||||||
{{$current := $realm.GetLongCodeDurationHours}} | ||||||
{{range $lch := .longCodeHours}} | ||||||
<option value="{{$lch}}" {{if (eq $lch $current)}}selected{{end}}>{{$lch}}</option> | ||||||
{{end}} | ||||||
</select> | ||||||
<small class="form-text text-muted"> | ||||||
The long code can be valid between <code>1</code> and <code>24</code> hours. | ||||||
</small> | ||||||
{{end}} | ||||||
</div> | ||||||
<div class="col-sm-1">hours</div> | ||||||
</div> | ||||||
|
@@ -188,7 +225,38 @@ <h1>Realm settings</h1> | |||||
The SMS message will be constructed based on the template you provide. The overall | ||||||
length of of the SMS message should not exceede 160 characters, or your message will need to be split | ||||||
in transit and may not be joined correctly. There are some special strings that you can use | ||||||
to substitute items. Your SMS template <em>MUST</em> contain either the <code>[code]</code> or | ||||||
to substitute items. | ||||||
{{if $realm.EnableENExpress}} | ||||||
Your SMS template <em>MUST</em> contain <code>[enslink]</code>. | ||||||
<ul> | ||||||
<li><code>[enslink]</code> Inserts the required EN Express link of: <code>ens://v?r=[region]&c=[longcode]</code></li> | ||||||
<li><code>[longexpires]</code>The number of hours until the long code expires (just the number, no units).</li> | ||||||
</ul> | ||||||
|
||||||
Here is an example SMS template using EN Express. | ||||||
|
||||||
<ul> | ||||||
<li> | ||||||
<p>Custom greeting before the EN Express link and showing expiration. | ||||||
This is <code>145</code> characters when expanded.</p> | ||||||
<p> | ||||||
<samp class="text-dark"> | ||||||
State of Wonder Dept. of Health. Click to share anonymous data for exposure notifications [enslink] Expires in [longexpires] hours | ||||||
</samp> | ||||||
</p> | ||||||
</li> | ||||||
<li> | ||||||
<p>This results in a SMS message that looks like:</p> | ||||||
<p> | ||||||
<samp class="text-dark"> | ||||||
State of Wonder Dept. of Health. Click to share anonymous data for exposure notifications ens://v?r=US-XX&c=12345678abcd1234 Expires in 24 hours | ||||||
</samp> | ||||||
</p> | ||||||
</li> | ||||||
</ul> | ||||||
|
||||||
{{else}} | ||||||
Your SMS template <em>MUST</em> contain either the <code>[code]</code> or | ||||||
<code>[longcode]</code>. | ||||||
<ul> | ||||||
<li><code>[region]</code>The region setting (set on this page).</li> | ||||||
|
@@ -222,6 +290,7 @@ <h1>Realm settings</h1> | |||||
</p> | ||||||
</li> | ||||||
</ul> | ||||||
{{end}} | ||||||
</small> | ||||||
</div> | ||||||
</div> | ||||||
|
@@ -268,6 +337,20 @@ <h1>Realm settings</h1> | |||||
</div> | ||||||
</div> | ||||||
</form> | ||||||
|
||||||
{{if $realm.EnableENExpress}} | ||||||
<div class="card mb-3"> | ||||||
<div class="card-header"> | ||||||
ENX - Exposure Notifications Express | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
</div> | ||||||
<div class="card-body"> | ||||||
<form method="POST" action="/realm/settings/disable-express"> | ||||||
{{ .csrfField }} | ||||||
<a href="#" class="btn btn-danger btn-block" data-confirm="Are you sure you want to disable EN Express? This could cause your iOS and Android integrations to stop working." data-submit-form>Disable EN Express</a> | ||||||
</form> | ||||||
</div> | ||||||
</div> | ||||||
{{end}} | ||||||
</main> | ||||||
|
||||||
{{template "scripts" .}} | ||||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -311,6 +311,8 @@ func realMain(ctx context.Context) error { | |
realmadminController := realmadmin.New(ctx, config, db, h) | ||
realmSub.Handle("/settings", realmadminController.HandleIndex()).Methods("GET") | ||
realmSub.Handle("/settings/save", realmadminController.HandleSave()).Methods("POST") | ||
realmSub.Handle("/settings/enable-express", realmadminController.HandleEnableExpress()).Methods("POST") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should technically be PATCH, but meh. |
||
realmSub.Handle("/settings/disable-express", realmadminController.HandleDisableExpress()).Methods("POST") | ||
|
||
realmKeysController, err := realmkeys.New(ctx, config, db, certificateSigner, h) | ||
if err != nil { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright 2020 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package realmadmin | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/google/exposure-notifications-verification-server/pkg/controller" | ||
"github.com/google/exposure-notifications-verification-server/pkg/database" | ||
) | ||
|
||
func (c *Controller) HandleDisableExpress() http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
|
||
session := controller.SessionFromContext(ctx) | ||
if session == nil { | ||
controller.MissingSession(w, r, c.h) | ||
return | ||
} | ||
flash := controller.Flash(session) | ||
|
||
realm := controller.RealmFromContext(ctx) | ||
if realm == nil { | ||
controller.MissingRealm(w, r, c.h) | ||
return | ||
} | ||
|
||
if !realm.EnableENExpress { | ||
flash.Error("Realm is not currently enrolled in EN Express.") | ||
c.renderShow(ctx, w, r, realm, nil) | ||
return | ||
} | ||
|
||
defaultSettings := database.NewRealmWithDefaults("--") | ||
realm.EnableENExpress = false | ||
realm.SMSTextTemplate = defaultSettings.SMSTextTemplate | ||
if err := c.db.SaveRealm(realm); err != nil { | ||
flash.Error("Failed to disable EN Express: %v", err) | ||
|
||
c.renderShow(ctx, w, r, realm, nil) | ||
return | ||
} | ||
|
||
flash.Alert("Successfully disabled EN Express") | ||
http.Redirect(w, r, "/realm/settings", http.StatusSeeOther) | ||
}) | ||
} | ||
|
||
func (c *Controller) HandleEnableExpress() http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
ctx := r.Context() | ||
|
||
session := controller.SessionFromContext(ctx) | ||
if session == nil { | ||
controller.MissingSession(w, r, c.h) | ||
return | ||
} | ||
flash := controller.Flash(session) | ||
|
||
realm := controller.RealmFromContext(ctx) | ||
if realm == nil { | ||
controller.MissingRealm(w, r, c.h) | ||
return | ||
} | ||
|
||
if realm.EnableENExpress { | ||
flash.Error("Realm already has EN Express Enabled.") | ||
c.renderShow(ctx, w, r, realm, nil) | ||
return | ||
} | ||
|
||
// Enable EN Express by setting default settings. | ||
enxSettings := database.NewRealmWithDefaults("--") | ||
realm.EnableENExpress = true | ||
realm.CodeLength = enxSettings.CodeLength | ||
realm.CodeDuration = enxSettings.CodeDuration | ||
realm.LongCodeLength = enxSettings.LongCodeLength | ||
realm.LongCodeDuration = enxSettings.LongCodeDuration | ||
realm.SMSTextTemplate = "This is your Exposure Notifications Verification code: [enslink] Expires in [longexpires] hours" | ||
// Confirmed is the only allowed test type for EN Express. | ||
realm.AllowedTestTypes = database.TestTypeConfirmed | ||
|
||
if err := c.db.SaveRealm(realm); err != nil { | ||
flash.Error("Failed to enable EN Express: %v", err) | ||
// This will allow the user to correct other validation errors and then click "uprade" again. | ||
realm.EnableENExpress = false | ||
realm.SMSTextTemplate = enxSettings.SMSTextTemplate | ||
c.renderShow(ctx, w, r, realm, nil) | ||
return | ||
} | ||
|
||
flash.Alert("Successfully enabled EN Express!") | ||
http.Redirect(w, r, "/realm/settings", http.StatusSeeOther) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We say "EN Express" everywhere else except these titles.