18676: move length check for AnonymousUserToken to lib/config, bring it
authorWard Vandewege <ward@curii.com>
Fri, 11 Feb 2022 17:46:00 +0000 (12:46 -0500)
committerWard Vandewege <ward@curii.com>
Fri, 11 Feb 2022 17:46:30 +0000 (12:46 -0500)
       in line with the other tokens, small tweaks from review comments.

Arvados-DCO-1.1-Signed-off-by: Ward Vandewege <ward@curii.com>

doc/admin/upgrading.html.textile.liquid
doc/install/install-keep-web.html.textile.liquid
lib/config/load.go
services/api/app/models/api_client_authorization.rb

index 9ad081292eff3324536a087d7b06203d78b29ede..05b932a116bea3578dbf3e21563f6745eef80208 100644 (file)
@@ -41,7 +41,7 @@ h2(#main). development main (as of 2022-02-10)
 
 h3. Anonymous token changes
 
-The anonymous token configured in @Users.AnonymousUserToken@ must now be 50 characters or longer. This was already the suggestion in the documentation, now it is enforced. The @script/get_anonymous_user_token.rb@ script that was needed to register the anonymous user token in the database has been removed. Registration of the anonymous token is no longer necessary.
+The anonymous token configured in @Users.AnonymousUserToken@ must now be 32 characters or longer. This was already the suggestion in the documentation, now it is enforced. The @script/get_anonymous_user_token.rb@ script that was needed to register the anonymous user token in the database has been removed. Registration of the anonymous token is no longer necessary.
 
 h3. Preemptible instance types are used automatically, if any are configured
 
index 4942c96078a56bac709232f8fb399459c19b6152..1ba9fc522fab9dbf69207d3fa67061e586843079 100644 (file)
@@ -107,7 +107,7 @@ h2(#update-config). Configure anonymous user token
 
 If you intend to use Keep-web to serve public data to anonymous clients, configure it with an anonymous token.
 
-Generate a random string (>= 50 characters long) and put it in the @config.yml@ file, in the @AnonymousUserToken@ field.
+Generate a random string (>= 32 characters long) and put it in the @config.yml@ file, in the @AnonymousUserToken@ field.
 
 <notextile>
 <pre><code>    Users:
index c2eb55554488f465a7dc990b87ad6da450459a4d..418a400e6267e48abb6194f0975e325fb00db4e6 100644 (file)
@@ -299,9 +299,10 @@ func (ldr *Loader) Load() (*arvados.Config, error) {
                for _, err = range []error{
                        ldr.checkClusterID(fmt.Sprintf("Clusters.%s", id), id, false),
                        ldr.checkClusterID(fmt.Sprintf("Clusters.%s.Login.LoginCluster", id), cc.Login.LoginCluster, true),
-                       ldr.checkToken(fmt.Sprintf("Clusters.%s.ManagementToken", id), cc.ManagementToken),
-                       ldr.checkToken(fmt.Sprintf("Clusters.%s.SystemRootToken", id), cc.SystemRootToken),
-                       ldr.checkToken(fmt.Sprintf("Clusters.%s.Collections.BlobSigningKey", id), cc.Collections.BlobSigningKey),
+                       ldr.checkToken(fmt.Sprintf("Clusters.%s.ManagementToken", id), cc.ManagementToken, true),
+                       ldr.checkToken(fmt.Sprintf("Clusters.%s.SystemRootToken", id), cc.SystemRootToken, true),
+                       ldr.checkToken(fmt.Sprintf("Clusters.%s.Users.AnonymousUserToken", id), cc.Users.AnonymousUserToken, false),
+                       ldr.checkToken(fmt.Sprintf("Clusters.%s.Collections.BlobSigningKey", id), cc.Collections.BlobSigningKey, true),
                        checkKeyConflict(fmt.Sprintf("Clusters.%s.PostgreSQL.Connection", id), cc.PostgreSQL.Connection),
                        ldr.checkEnum("Containers.LocalKeepLogsToContainerLog", cc.Containers.LocalKeepLogsToContainerLog, "none", "all", "errors"),
                        ldr.checkEmptyKeepstores(cc),
@@ -333,14 +334,15 @@ func (ldr *Loader) checkClusterID(label, clusterID string, emptyStringOk bool) e
 var acceptableTokenRe = regexp.MustCompile(`^[a-zA-Z0-9]+$`)
 var acceptableTokenLength = 32
 
-func (ldr *Loader) checkToken(label, token string) error {
-       if token == "" {
+func (ldr *Loader) checkToken(label, token string, mandatory bool) error {
+       // when a token is not mandatory, the acceptable length and content is only checked if its length is non-zero
+       if mandatory && token == "" {
                if ldr.Logger != nil {
                        ldr.Logger.Warnf("%s: secret token is not set (use %d+ random characters from a-z, A-Z, 0-9)", label, acceptableTokenLength)
                }
-       } else if !acceptableTokenRe.MatchString(token) {
+       } else if (mandatory || len(token) > 0) && !acceptableTokenRe.MatchString(token) {
                return fmt.Errorf("%s: unacceptable characters in token (only a-z, A-Z, 0-9 are acceptable)", label)
-       } else if len(token) < acceptableTokenLength {
+       } else if (mandatory || len(token) > 0) && len(token) < acceptableTokenLength {
                if ldr.Logger != nil {
                        ldr.Logger.Warnf("%s: token is too short (should be at least %d characters)", label, acceptableTokenLength)
                }
index f4bf4f0698ba79f7c712c6fccb3399efd35d18c3..a6beaa07ab38b6a177e9a466f7cd50f737b0edaa 100644 (file)
@@ -124,7 +124,8 @@ class ApiClientAuthorization < ArvadosModel
       secret = token
     end
 
-    if secret.length >= 50 and secret == Rails.configuration.Users.AnonymousUserToken
+    # The anonymous token content and minimum length is verified in lib/config
+    if secret.length >= 0 && secret == Rails.configuration.Users.AnonymousUserToken
       return ApiClientAuthorization.new(user: User.find_by_uuid(anonymous_user_uuid),
                                         uuid: Rails.configuration.ClusterID+"-gj3su-anonymouspublic",
                                         api_token: token,