Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package gnuhealth-thalamus for 
openSUSE:Factory checked in at 2021-03-11 20:11:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/gnuhealth-thalamus (Old)
 and      /work/SRC/openSUSE:Factory/.gnuhealth-thalamus.new.2401 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "gnuhealth-thalamus"

Thu Mar 11 20:11:13 2021 rev:7 rq:878228 version:0.9.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/gnuhealth-thalamus/gnuhealth-thalamus.changes    
2020-02-24 15:54:03.731693093 +0100
+++ 
/work/SRC/openSUSE:Factory/.gnuhealth-thalamus.new.2401/gnuhealth-thalamus.changes
  2021-03-11 20:12:53.276721601 +0100
@@ -1,0 +2,5 @@
+Wed Mar  3 19:47:37 UTC 2021 - Axel Braun <axel.br...@gmx.de>
+
+- version 0.9.13 fixes https://savannah.gnu.org/bugs/?60164
+
+-------------------------------------------------------------------

Old:
----
  thalamus-0.9.12.tar.gz

New:
----
  thalamus-0.9.13.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ gnuhealth-thalamus.spec ++++++
--- /var/tmp/diff_new_pack.Vg9lSP/_old  2021-03-11 20:12:53.844722523 +0100
+++ /var/tmp/diff_new_pack.Vg9lSP/_new  2021-03-11 20:12:53.848722529 +0100
@@ -1,8 +1,8 @@
 #
 # spec file for package gnuhealth-thalamus
 #
-# Copyright (c) 2020 SUSE LLC
-# Copyright (c) 2017-2020 Dr. Axel Braun
+# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2017-2021 Dr. Axel Braun
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
 
 %define modname thalamus
 Name:           gnuhealth-%{modname}
-Version:        0.9.12
+Version:        0.9.13
 Release:        0
 Summary:        The GNU Health Federation Message and Authentication Server
 License:        GPL-3.0-or-later

++++++ thalamus-0.9.12.tar.gz -> thalamus-0.9.13.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/PKG-INFO new/thalamus-0.9.13/PKG-INFO
--- old/thalamus-0.9.12/PKG-INFO        2019-11-20 09:20:03.000000000 +0100
+++ new/thalamus-0.9.13/PKG-INFO        2021-03-03 20:13:30.480479000 +0100
@@ -1,14 +1,14 @@
 Metadata-Version: 1.1
 Name: thalamus
-Version: 0.9.12
+Version: 0.9.13
 Summary: The GNU Health Federation Message and Authentication Server
 Home-page: http://health.gnu.org
 Author: GNU Solidario
 Author-email: hea...@gnusolidario.org
 License: UNKNOWN
 Download-URL: http://ftp.gnu.org/gnu/health
-Description: Thalamus: The GNU Health Message and Authentication Server
-        ==========================================================
+Description: Thalamus: The GNU Health Federation Message and Authentication 
Server
+        =====================================================================
         
         The Thalamus project provides a RESTful API hub to all the GNU Health 
         Federation nodes. The main functions are:
@@ -30,7 +30,7 @@
         ------------
         Thalamus is pip-installable::
         
-          $ pip3 install --upgrade --user thalamus 
+          $ pip3 install --upgrade --user thalamus
          
         Technology
         ----------
@@ -91,91 +91,139 @@
         
         Retrieve the demographic information of person::
         
-          $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people/ESPGNU777ORG
+          $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people/ESPGNU777ORG
+        
         
         Yields to::
         
             HTTP/1.1 200 OK
+            Access-Control-Allow-Origin: *
             Connection: close
-            Content-Length: 411
+            Content-Length: 547
             Content-Type: application/json
-            Date: Fri, 21 Apr 2017 16:22:38 GMT
-            Server: gunicorn/19.7.1
+            Date: Thu, 30 Jul 2020 12:01:37 GMT
+            Server: gunicorn/20.0.0
         
             {
                 "_id": "ESPGNU777ORG",
                 "active": true,
-                "biological_sex": "female",
-                "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
+                "dob": "1990-10-04",
                 "education": "tertiary",
                 "ethnicity": "latino",
-                "gender": "female",
+                "gender": "f",
+                "id": "ESPGNU777ORG",
                 "lastname": "Betz",
                 "marital_status": "married",
+                "modification_info": {
+                    "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL",
+                    "timestamp": "2018-11-06 19:24:43.662846",
+                    "user": "ITAPYT999HON"
+                },
                 "name": "Ana",
                 "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
                 "profession": "teacher",
                 "roles": [
-                "end_user"
+                    "end_user"
                 ]
-                
             }
         
         **Retrieve the demographics information globally**::
         
-          $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people
+          $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people
         
         Yields to::
         
-            HTTP/1.1 200 OK
-            Connection: close
-            Content-Length: 933
-            Content-Type: application/json
-            Date: Fri, 21 Apr 2017 16:31:23 GMT
-            Server: gunicorn/19.7.1
+            HTTP/1.1 200 OK 
+            Access-Control-Allow-Origin: * 
+            Connection: close 
+            Content-Length: 2715 
+            Content-Type: application/json 
+            Date: Mon, 20 Jul 2020 18:03:24 GMT 
+            Server: gunicorn/20.0.0 
+        
+            [ 
+            [ 
+                { 
+                    "active": true, 
+                    "dob": "1984-10-05", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ITAPYT999HON", 
+                    "lastname": "Cordara", 
+                    "marital_status": "married", 
+                    "name": "Cameron", 
+                    "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2", 
+                    "profession": "teacher", 
+                    "roles": [ 
+                        "end_user", 
+                        "health_professional" 
+                    ] 
+                } 
+            ],
+            [ 
+                { 
+                    "creation_info": { 
+                        "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                        "timestamp": "2019-11-20 10:39:21.162731", 
+                        "user": "ITAPYT999HON" 
+                    }, 
+                    "dob": "1999-10-12", 
+                    "gender": "m", 
+                    "id": "DEUMOP095IDI", 
+                    "lastname": "Dillinger", 
+                    "name": "John Doe???", 
+                    "roles": [ 
+                        "end_user" 
+                    ] 
+                } 
+            ],
         
-            [
-                {
-                    "_id": "ITAPYT999HON",
-                    "active": true,
-                    "biological_sex": "female",
-                    "dob": "Fri, 05 Oct 1984 09:00:00 GMT",
-                    "education": "tertiary",
-                    "ethnicity": "latino",
-                    "gender": "female",
-                    "lastname": "Cordara",
-                    "marital_status": "married",
-                    "name": "Cameron",
-                    "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2",
-                    "profession": "teacher",
-                    "roles": [
-                    "end_user",
-                    "health_professional"
-                    ]
-                    
-                },
-                
-                {
-                    "_id": "ESPGNU777ORG",
-                    "active": true,
-                    "biological_sex": "female",
-                    "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
-                    "education": "tertiary",
-                    "ethnicity": "latino",
-                    "gender": "female",
-                    "lastname": "Betz",
-                    "marital_status": "married",
-                    "name": "Ana",
-                    "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
-                    "profession": "teacher",
-                    "roles": [
-                    "end_user"
-                    ]
-                    
-                }
-                
-            ]
             
+            [ 
+                { 
+                    "active": true, 
+                    "dob": "2008-10-12", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ARGBUE111FAV", 
+                    "lastname": "Root", 
+                    "marital_status": "married", 
+                    "name": "Admin", 
+                    "password": 
"$2b$12$McKDNgArdHKbUssD1fj64ecpdbJGMIt29ns7DGvqzqIT26W0dtJzi", 
+                    "profession": "System Administrator", 
+                    "roles": [ 
+                        "root" 
+                    ] 
+                } 
+            ], 
+            [ 
+                { 
+                    "_id": "ESPGNU777ORG", 
+                    "active": true, 
+                    "dob": "1990-10-04", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ESPGNU777ORG", 
+                    "lastname": "Betz", 
+                    "marital_status": "married", 
+                    "modification_info": { 
+                        "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                        "timestamp": "2018-11-06 19:24:43.662846", 
+                        "user": "ITAPYT999HON" 
+                    }, 
+                    "name": "Ana", 
+                    "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW", 
+                    "profession": "teacher", 
+                    "roles": [ 
+                        "end_user" 
+                    ] 
+                } 
+            ], 
+            ]
+        
         
         **Using Python requests**::
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/README.rst 
new/thalamus-0.9.13/README.rst
--- old/thalamus-0.9.12/README.rst      2019-11-20 09:03:38.000000000 +0100
+++ new/thalamus-0.9.13/README.rst      2021-03-03 20:12:13.000000000 +0100
@@ -1,5 +1,5 @@
-Thalamus: The GNU Health Message and Authentication Server
-==========================================================
+Thalamus: The GNU Health Federation Message and Authentication Server
+=====================================================================
 
 The Thalamus project provides a RESTful API hub to all the GNU Health 
 Federation nodes. The main functions are:
@@ -21,7 +21,7 @@
 ------------
 Thalamus is pip-installable::
 
-  $ pip3 install --upgrade --user thalamus 
+  $ pip3 install --upgrade --user thalamus
  
 Technology
 ----------
@@ -82,91 +82,139 @@
 
 Retrieve the demographic information of person::
 
-  $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people/ESPGNU777ORG
+  $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people/ESPGNU777ORG
+
 
 Yields to::
 
     HTTP/1.1 200 OK
+    Access-Control-Allow-Origin: *
     Connection: close
-    Content-Length: 411
+    Content-Length: 547
     Content-Type: application/json
-    Date: Fri, 21 Apr 2017 16:22:38 GMT
-    Server: gunicorn/19.7.1
+    Date: Thu, 30 Jul 2020 12:01:37 GMT
+    Server: gunicorn/20.0.0
 
     {
         "_id": "ESPGNU777ORG",
         "active": true,
-        "biological_sex": "female",
-        "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
+        "dob": "1990-10-04",
         "education": "tertiary",
         "ethnicity": "latino",
-        "gender": "female",
+        "gender": "f",
+        "id": "ESPGNU777ORG",
         "lastname": "Betz",
         "marital_status": "married",
+        "modification_info": {
+            "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL",
+            "timestamp": "2018-11-06 19:24:43.662846",
+            "user": "ITAPYT999HON"
+        },
         "name": "Ana",
         "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
         "profession": "teacher",
         "roles": [
-        "end_user"
+            "end_user"
         ]
-        
     }
 
 **Retrieve the demographics information globally**::
 
-  $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people
+  $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people
 
 Yields to::
 
-    HTTP/1.1 200 OK
-    Connection: close
-    Content-Length: 933
-    Content-Type: application/json
-    Date: Fri, 21 Apr 2017 16:31:23 GMT
-    Server: gunicorn/19.7.1
+    HTTP/1.1 200 OK 
+    Access-Control-Allow-Origin: * 
+    Connection: close 
+    Content-Length: 2715 
+    Content-Type: application/json 
+    Date: Mon, 20 Jul 2020 18:03:24 GMT 
+    Server: gunicorn/20.0.0 
+
+    [ 
+    [ 
+        { 
+            "active": true, 
+            "dob": "1984-10-05", 
+            "education": "tertiary", 
+            "ethnicity": "latino", 
+            "gender": "f", 
+            "id": "ITAPYT999HON", 
+            "lastname": "Cordara", 
+            "marital_status": "married", 
+            "name": "Cameron", 
+            "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2", 
+            "profession": "teacher", 
+            "roles": [ 
+                "end_user", 
+                "health_professional" 
+            ] 
+        } 
+    ],
+    [ 
+        { 
+            "creation_info": { 
+                "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                "timestamp": "2019-11-20 10:39:21.162731", 
+                "user": "ITAPYT999HON" 
+            }, 
+            "dob": "1999-10-12", 
+            "gender": "m", 
+            "id": "DEUMOP095IDI", 
+            "lastname": "Dillinger", 
+            "name": "John Doe???", 
+            "roles": [ 
+                "end_user" 
+            ] 
+        } 
+    ],
 
-    [
-        {
-            "_id": "ITAPYT999HON",
-            "active": true,
-            "biological_sex": "female",
-            "dob": "Fri, 05 Oct 1984 09:00:00 GMT",
-            "education": "tertiary",
-            "ethnicity": "latino",
-            "gender": "female",
-            "lastname": "Cordara",
-            "marital_status": "married",
-            "name": "Cameron",
-            "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2",
-            "profession": "teacher",
-            "roles": [
-            "end_user",
-            "health_professional"
-            ]
-            
-        },
-        
-        {
-            "_id": "ESPGNU777ORG",
-            "active": true,
-            "biological_sex": "female",
-            "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
-            "education": "tertiary",
-            "ethnicity": "latino",
-            "gender": "female",
-            "lastname": "Betz",
-            "marital_status": "married",
-            "name": "Ana",
-            "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
-            "profession": "teacher",
-            "roles": [
-            "end_user"
-            ]
-            
-        }
-        
-    ]
     
+    [ 
+        { 
+            "active": true, 
+            "dob": "2008-10-12", 
+            "education": "tertiary", 
+            "ethnicity": "latino", 
+            "gender": "f", 
+            "id": "ARGBUE111FAV", 
+            "lastname": "Root", 
+            "marital_status": "married", 
+            "name": "Admin", 
+            "password": 
"$2b$12$McKDNgArdHKbUssD1fj64ecpdbJGMIt29ns7DGvqzqIT26W0dtJzi", 
+            "profession": "System Administrator", 
+            "roles": [ 
+                "root" 
+            ] 
+        } 
+    ], 
+    [ 
+        { 
+            "_id": "ESPGNU777ORG", 
+            "active": true, 
+            "dob": "1990-10-04", 
+            "education": "tertiary", 
+            "ethnicity": "latino", 
+            "gender": "f", 
+            "id": "ESPGNU777ORG", 
+            "lastname": "Betz", 
+            "marital_status": "married", 
+            "modification_info": { 
+                "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                "timestamp": "2018-11-06 19:24:43.662846", 
+                "user": "ITAPYT999HON" 
+            }, 
+            "name": "Ana", 
+            "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW", 
+            "profession": "teacher", 
+            "roles": [ 
+                "end_user" 
+            ] 
+        } 
+    ], 
+    ]
+
 
 **Using Python requests**::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/setup.py new/thalamus-0.9.13/setup.py
--- old/thalamus-0.9.12/setup.py        2019-10-04 22:48:23.000000000 +0200
+++ new/thalamus-0.9.13/setup.py        2021-03-03 20:12:31.000000000 +0100
@@ -8,8 +8,8 @@
 #
 ##############################################################################
 #
-#    Copyright (C) 2008 - 2019 Luis Falcon <lfal...@gnusolidario.org>
-#    Copyright (C) 2008 - 2019 GNU Solidario <hea...@gnusolidario.org>
+#    Copyright (C) 2008 - 2021 Luis Falcon <fal...@gnuhealth.org>
+#    Copyright (C) 2008 - 2021 GNU Solidario <hea...@gnusolidario.org>
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -28,21 +28,22 @@
 
 from setuptools import setup, find_packages
 
-long_desc = open("README.rst", "r").read()
+long_desc = open("README.rst").read()
 
 version = open("version").read().strip()
 
 setup(name='thalamus',
-    version=version,
-    description = 'The GNU Health Federation Message and Authentication 
Server',
-    keywords='health API REST',
-    long_description = long_desc,
-    platforms='any',
-    author='GNU Solidario',
-    author_email='hea...@gnusolidario.org',
-    url='http://health.gnu.org',
-    download_url='http://ftp.gnu.org/gnu/health',
-    classifiers=[
+      version=version,
+      description='The GNU Health Federation Message'
+                  ' and Authentication Server',
+      keywords='health API REST',
+      long_description=long_desc,
+      platforms='any',
+      author='GNU Solidario',
+      author_email='hea...@gnusolidario.org',
+      url='http://health.gnu.org',
+      download_url='http://ftp.gnu.org/gnu/health',
+      classifiers=[
         'Development Status :: 4 - Beta',
         'Environment :: Web Environment',
         'Framework :: Flask',
@@ -55,15 +56,15 @@
         'Topic :: Scientific/Engineering :: Bio-Informatics',
         'Topic :: Scientific/Engineering :: Medical Science Apps.',
         ],
-    install_requires = [
+      install_requires=[
         "flask", 
         "flask_httpauth",
         "flask_restful",
         "flask_wtf",
         "psycopg2-binary",
         "bcrypt",
-    ],
-    packages=find_packages(),
-    include_package_data=True,
-    zip_safe=False,
- )
+      ],
+      packages=find_packages(),
+      include_package_data=True,
+      zip_safe=False,
+      )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/thalamus/thalamus.py 
new/thalamus-0.9.13/thalamus/thalamus.py
--- old/thalamus-0.9.12/thalamus/thalamus.py    2019-11-20 09:03:38.000000000 
+0100
+++ new/thalamus-0.9.13/thalamus/thalamus.py    2021-03-03 19:28:32.000000000 
+0100
@@ -8,8 +8,8 @@
 ##############################################################################
 #
 #    GNU Health: The Free Health and Hospital Information System
-#    Copyright (C) 2008-2019 Luis Falcon <fal...@gnuhealth.org>
-#    Copyright (C) 2011-2019 GNU Solidario <hea...@gnusolidario.org>
+#    Copyright (C) 2008-2021 Luis Falcon <fal...@gnuhealth.org>
+#    Copyright (C) 2011-2021 GNU Solidario <hea...@gnusolidario.org>
 #
 #    This program is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
@@ -41,7 +41,8 @@
 import bcrypt
 import logging
 
-__all__ = ["People","Person","Book","Page", "Login", "PasswordForm","Password"]
+__all__ = ["People", "Person", "Book", "Page", "Login",
+           "PasswordForm", "Password"]
 
 app = Flask(__name__)
 
@@ -54,7 +55,7 @@
 
 auth = HTTPBasicAuth()
 
-ACL = json.load(open(app.config['ACL'],'r'))
+ACL = json.load(open(app.config['ACL'], 'r'))
 
 # Use Gunicorn logging system when Thalamus is run through it
 # use the gunicorn argument --log-level to specify the starting
@@ -65,18 +66,19 @@
     app.logger.setLevel(gunicorn_logger.level)
 
 
-#Open a connection to PG Server
+# Open a connection to PG Server
 conn = psycopg2.connect(app.config['POSTGRESQL_URI'])
 
+
 def check_id(table, resid):
     """
     Checks if the Federation ID exists on the GNU Health HIS
     Returns the instance or null
     """
     cur = conn.cursor()
-    cur.execute (
-        sql.SQL("SELECT id from {} where id = %s 
limit(1)").format(sql.Identifier(table)), \
-            (resid,))
+    cur.execute(
+        sql.SQL("SELECT id from {} where id = %s \
+                limit(1)").format(sql.Identifier(table)), (resid,))
     try:
         res, = cur.fetchone()
     except:
@@ -86,6 +88,7 @@
 
 # Authentication
 
+
 @auth.verify_password
 def verify_password(username, password):
     """
@@ -94,7 +97,7 @@
     The password is bcrypt hashed
     """
     cur = conn.cursor()
-    cur.execute ('SELECT data from people \
+    cur.execute('SELECT data from people \
         where id = %s limit(1)', (username,))
     try:
         user, = cur.fetchone()
@@ -106,14 +109,14 @@
         hashed_password = user['password']
         roles = user['roles']
         if bcrypt.checkpw(password.encode('utf-8'),
-            hashed_password.encode('utf-8')):
+                          hashed_password.encode('utf-8')):
             """ Authentication OK
             Now check the access level for the resource
             """
             method = request.method
             endpoint = request.endpoint
             view_args = request.view_args
-            return access_control(username,roles, method, endpoint, view_args)
+            return access_control(username, roles, method, endpoint, view_args)
 
         else:
             return False
@@ -122,7 +125,6 @@
         return False
 
 
-
 # Authorization
 def access_control(username, roles, method, endpoint, view_args):
     """
@@ -140,40 +142,43 @@
                             whether the user role has global access
                             or just can see his/her records"""
                         if (username == view_args["person_id"] or
-                            actions["global"] == "True"):
-                                return True
+                                actions["global"] == "True"):
+                            return True
                     else:
                         return True
     return False
 
+
 # People Resource
 class People(Resource):
     """Collection resource for demographic information"""
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
+
     def get(self):
         """
         Retrieves all the people on the person collection
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from people')
+        cur.execute('SELECT data from people')
         people = cur.fetchall()
 
         return jsonify(people)
 
+
 # Person
 class Person(Resource):
     """Class that manages the person demographics.
     """
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self, person_id):
         """
         Retrieves the person instance
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from people \
+        cur.execute('SELECT data from people \
             where id = %s limit(1)', (person_id,))
 
         try:
@@ -194,83 +199,80 @@
         hashed password
         """
 
-        #Grab the data coming from the client, in JSON format
+        # Grab the data coming from the client, in JSON format
         values = json.loads(request.data)
 
         # Initialize to inactive the newly created person
-        #values['active'] = False
+        # values['active'] = False
         pw = None
 
         bcrypt_prefixes = ["$2b$", "$2y$"]
 
         if check_id('people', person_id):
-            abort (422, error="User already exists")
+            abort(422, error="User already exists")
 
         if (person_id):
             if (type(person_id) is str):
-                #Use upper case on the person federation account
+                # Use upper case on the person federation account
                 person_id = person_id.upper()
                 values['id'] = person_id
         else:
-            abort (422, error="wrong format on person ID")
+            abort(422, error="wrong format on person ID")
 
-        #If no roles are supplied, assign "end_user"
+        # If no roles are supplied, assign "end_user"
         if not ('roles' in values.keys()):
             values['roles'] = ["end_user"]
 
-
         if ('password' in values.keys()):
             pw = values['password']
 
         if (pw):
             if (len(pw) > 64):
-                abort (422, error="Password is too long")
+                abort(422, error="Password is too long")
 
             # Check if the password is already in bcrypt format
             if (pw[0:4] in bcrypt_prefixes):
                 hashed_pw = pw
             else:
                 hashed_pw = (bcrypt.hashpw(pw.encode('utf-8'),
-                    bcrypt.gensalt())).decode('utf-8')
-
+                                           bcrypt.gensalt())).decode('utf-8')
             values['password'] = hashed_pw
 
         # Insert the newly created person
         cur = conn.cursor()
         cur.execute("INSERT INTO people (ID, DATA) VALUES (%(id)s, \
-            %(data)s)", {'id': person_id, 'data':json.dumps(values)})
+            %(data)s)", {'id': person_id, 'data': json.dumps(values)})
         res = conn.commit()
 
         return res
 
-
     def patch(self, person_id):
         """
         Updates the person instance
         """
 
-        #Grab all the data coming from the node client, in JSON format
+        # Grab all the data coming from the node client, in JSON format
         values = json.loads(request.data)
 
         if 'id' in values:
             # Avoid changing the user ID
-            print ("Not allowed to change the person ID")
+            print("Not allowed to change the person ID")
             abort(422, error="Not allowed to change the person ID")
             # TO be discussed...
             # Check if the new ID exist in the Federation, and if it
             # does not, we may be able to update it.
 
-        if check_id('people',person_id):
+        if check_id('people', person_id):
             jdata = json.dumps(values)
             # UPDATE the information from the person
             # associated to the federation ID
             cur = conn.cursor()
-            cur.execute("UPDATE PEOPLE SET data = data || %s where id = %s", \
-                (jdata,person_id))
+            cur.execute("UPDATE PEOPLE SET data = data || %s where id = %s",
+                        (jdata, person_id))
             conn.commit()
 
         else:
-            abort (404, error="User not found")
+            abort(404, error="User not found")
 
     def delete(self, person_id):
         """
@@ -280,35 +282,35 @@
         """
         person = check_id('people', person_id)
         if not person:
-            abort (404, error="User does not exist")
+            abort(404, error="User does not exist")
 
         else:
-           if person['active']:
-            abort (422, error="The user is active.")
+            if person['active']:
+                abort(422, error="The user is active.")
 
-        #Delete the person
+        # Delete the person
         cur = conn.cursor()
         cur.execute("DELETE FROM people WHERE id = %s", (person_id,))
         conn.commit()
 
+
 # Book of Life Resource
 class Book(Resource):
     """Collection resource for a person life information"""
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self, person_id):
         """
         Retrieves the pages of life from the person
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from pols where book = %s', (person_id,))
+        cur.execute('SELECT data from pols where book = %s', (person_id,))
         pages = cur.fetchall()
 
         return jsonify(pages)
 
-
-        # Return a 404 if the person ID is not found
+        #  Return a 404 if the person ID is not found
         if not pages:
             return '', 404
 
@@ -319,24 +321,23 @@
 class Page(Resource):
     """Information and events that make and shape a person life"""
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self, person_id, page_id):
         """
         Retrieves the page instance
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from pols \
+        cur.execute('SELECT data from pols \
             where id = %s limit(1)', (page_id,))
         try:
             page, = cur.fetchone()
         except:
             page = None
 
-
-        # Return a 404 if the page ID is not found
+        #  Return a 404 if the page ID is not found
         if not page:
-            abort (404, error="Book or page or not found")
+            abort(404, error="Book or page or not found")
 
         return jsonify(page)
 
@@ -344,9 +345,14 @@
         """
         Create a new instance on the Page resource
         """
-        #Grab the data coming from the client, in JSON format
+        # Grab the data coming from the client, in JSON format
         values = json.loads(request.data)
 
+        if not check_id('people', person_id):
+            app.logger.error(f"Person not found when trying"
+                             f" to create book {person_id}")
+            abort(404, error="Person not found")
+
         # Basic validation on page ID exsistance and string type
         if (person_id and 'id' in values):
             if (type(person_id) is str and type(values['id'])):
@@ -354,14 +360,15 @@
                 # Insert the newly created Page of Life from the person Book
                 cur = conn.cursor()
                 cur.execute("INSERT INTO pols (ID, BOOK, DATA) \
-                    VALUES (%(id)s, %(book)s, %(data)s)", \
-                    {'id': page_id, 'book': person_id, \
-                    'data':json.dumps(values)})
+                            VALUES (%(id)s, %(book)s, %(data)s)",
+                            {'id': page_id, 'book': person_id,
+                             'data': json.dumps(values)})
+
                 res = conn.commit()
 
         else:
-            print ("wrong format on person or page ID")
-            abort (422, error="wrong format on person or page ID")
+            print("wrong format on person or page ID")
+            abort(422, error="wrong format on person or page ID")
 
         return jsonify(res)
 
@@ -369,91 +376,97 @@
         """
         Updates the Page of Life
         """
-        #Grab all the data coming from the node client, in JSON format
+        #  Grab all the data coming from the node client, in JSON format
         values = json.loads(request.data)
 
         if 'id' in values:
             # Avoid changing the page ID
             abort(422, error="Not allowed to change the page ID")
 
-        if check_id('pols',page_id):
+        if check_id('pols', page_id):
 
             jdata = json.dumps(values)
             # UPDATE the information from the page
             # associated to the federation ID book
             cur = conn.cursor()
-            cur.execute("UPDATE pols SET data = data || %s where id = %s", \
-                (jdata,page_id))
+            cur.execute("UPDATE pols SET data = data || %s where id = %s",
+                        (jdata, page_id))
             conn.commit()
 
         else:
-            abort (404, error="Page not found")
+            abort(404, error="Page not found")
 
 # Add resources and endpoints
 # The endpoints are the class names in lower case (eg, people, life, page...)
 
-#People and person
-api.add_resource(People, '/people') #Add resource for People
-api.add_resource(Person, '/people/<string:person_id>') #Add person instance
 
-#Book and pages of life resources (in pols collection)
+# People and person
+api.add_resource(People, '/people')  # Add resource for People
+api.add_resource(Person, '/people/<string:person_id>')  # Add person instance
+
+# Book and pages of life resources (in pols collection)
 api.add_resource(Book, '/pols/<string:person_id>')
 api.add_resource(Page, '/pols/<string:person_id>/<string:page_id>')
 
+
 # Personal Documents resource
 class PersonalDocs(Resource):
     "Documents associated to the person (scanned info, birth certs, ..)"
-
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self, person_id):
         """
         Retrieves the documents of a person
         """
         cur = conn.cursor()
-        cur.execute ('SELECT fedacct, pol, data, document from personal_docs \
+        cur.execute('SELECT fedacct, pol, data, document from personal_docs \
             where fedacct = %s', (person_id,))
         documents = cur.fetchall()
 
         return jsonify(documents)
 
+
 api.add_resource(PersonalDocs, '/personal_docs/<string:person_id>')
 
+
 # Documents associated to a Page of Life
 class PolDocs(Resource):
     "Documents associated to the person in the context of a Page of Life"
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self, person_id, pol_id):
         """
         Retrieves the documents of a person
         """
         cur = conn.cursor()
-        cur.execute ('SELECT fedacct, pol, data, document from personal_docs \
-            where fedacct = %s', (person_id,pol_id))
+        cur.execute('SELECT fedacct, pol, data, document from personal_docs \
+            where fedacct = %s', (person_id, pol_id))
         documents = cur.fetchall()
 
         return jsonify(documents)
 
+
 api.add_resource(PolDocs, '/personal_docs/<string:person_id>/<string:pol_id>')
 
+
 # Domiciliary Units resource
 class DomiciliaryUnits(Resource):
     "Domiciliary Units"
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self):
         """
         Retrieves the Domiciliary Units
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from dus')
+        cur.execute('SELECT data from dus')
         dus = cur.fetchall()
 
         return jsonify(dus)
 
+
 api.add_resource(DomiciliaryUnits, '/domiciliary-units')
 
 
@@ -461,43 +474,51 @@
 class Institutions(Resource):
     "Health and other institutions"
 
-    decorators = [auth.login_required] # Use the decorator from httpauth
+    decorators = [auth.login_required]  # Use the decorator from httpauth
+
     def get(self):
         """
         Retrieves the Institutions
         """
         cur = conn.cursor()
-        cur.execute ('SELECT data from institutions')
+        cur.execute('SELECT data from institutions')
         institutions = cur.fetchall()
 
         return jsonify(institutions)
 
+
 api.add_resource(Institutions, '/institutions')
 
+
 # Login 
 class Login(Resource):
     """"
-    Main class for loggin in from another resources, such the GH Federation 
Portal
+    Main class for loggin in from another resources,
+    such the GH Federation Portal
     At this point, with the decorator auth.login_required is enough
     """
-    
-    decorators = [auth.login_required] # Use the decorator from httpauth
+
+    decorators = [auth.login_required]  # Use the decorator from httpauth
 
     def get(self):
         return True 
 
-api.add_resource(Login, '/login')
 
+api.add_resource(Login, '/login')
 
 
 class PasswordForm(FlaskForm):
     password = PasswordField('Password',
-        validators=[validators.DataRequired(),
-        validators.Length(min=6, max=30),
-        validators.EqualTo('pconfirm', message='Password mistmatch')])
+                             validators=[validators.DataRequired(),
+                                         validators.Length(min=6, max=30),
+                                         validators.EqualTo('pconfirm',
+                                                            message='Password \
+                                                            mistmatch'
+                                                            )])
     pconfirm = PasswordField('Confirm Password')
     update = SubmitField('Update')
 
+
 # Update the password of the user with a form
 @app.route('/password/<person_id>', methods=('GET', 'POST'))
 @auth.login_required
@@ -505,30 +526,33 @@
     error = None
     form = PasswordForm()
     if (request.method == 'POST' and form.validate()):
-            pwd = form.password.data.encode()
-            enc_pwd = bcrypt.hashpw(pwd, bcrypt.gensalt()).decode()
-            values = {'password': enc_pwd}
+        pwd = form.password.data.encode()
+        enc_pwd = bcrypt.hashpw(pwd, bcrypt.gensalt()).decode()
+        values = {'password': enc_pwd}
+
+        jdata = json.dumps(values)
+        # UPDATE the information from the person
+        # associated to the federation ID
+        cur = conn.cursor()
+        cur.execute("UPDATE PEOPLE SET data = data || %s where id = %s",
+                    (jdata, person_id))
+        update_password = cur.rowcount
+        conn.commit()
 
-            jdata = json.dumps(values)
-            # UPDATE the information from the person
-            # associated to the federation ID 
-            cur = conn.cursor()
-            cur.execute("UPDATE PEOPLE SET data = data || %s where id = %s", \
-                (jdata,person_id))
-            update_password = cur.rowcount
-            conn.commit()
+        if update_password > 0:
+            return redirect(url_for('index'))
+        else:
+            error = "Error updating the password"
+
+    return render_template('password.html', form=form,
+                           fed_account=person_id, error=error)
 
-            if update_password > 0:
-                return redirect(url_for('index'))
-            else:
-                error = "Error updating the password"
-    return render_template('password.html', form=form, \
-        fed_account=person_id, error=error)
 
 @app.route('/')
 def index():
     return render_template('index.html')
 
+
 if __name__ == '__main__':
     app.logger.warning("Running Thalamus without gunicorn ...")
     app.run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/thalamus.egg-info/PKG-INFO 
new/thalamus-0.9.13/thalamus.egg-info/PKG-INFO
--- old/thalamus-0.9.12/thalamus.egg-info/PKG-INFO      2019-11-20 
09:20:03.000000000 +0100
+++ new/thalamus-0.9.13/thalamus.egg-info/PKG-INFO      2021-03-03 
20:13:30.000000000 +0100
@@ -1,14 +1,14 @@
 Metadata-Version: 1.1
 Name: thalamus
-Version: 0.9.12
+Version: 0.9.13
 Summary: The GNU Health Federation Message and Authentication Server
 Home-page: http://health.gnu.org
 Author: GNU Solidario
 Author-email: hea...@gnusolidario.org
 License: UNKNOWN
 Download-URL: http://ftp.gnu.org/gnu/health
-Description: Thalamus: The GNU Health Message and Authentication Server
-        ==========================================================
+Description: Thalamus: The GNU Health Federation Message and Authentication 
Server
+        =====================================================================
         
         The Thalamus project provides a RESTful API hub to all the GNU Health 
         Federation nodes. The main functions are:
@@ -30,7 +30,7 @@
         ------------
         Thalamus is pip-installable::
         
-          $ pip3 install --upgrade --user thalamus 
+          $ pip3 install --upgrade --user thalamus
          
         Technology
         ----------
@@ -91,91 +91,139 @@
         
         Retrieve the demographic information of person::
         
-          $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people/ESPGNU777ORG
+          $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people/ESPGNU777ORG
+        
         
         Yields to::
         
             HTTP/1.1 200 OK
+            Access-Control-Allow-Origin: *
             Connection: close
-            Content-Length: 411
+            Content-Length: 547
             Content-Type: application/json
-            Date: Fri, 21 Apr 2017 16:22:38 GMT
-            Server: gunicorn/19.7.1
+            Date: Thu, 30 Jul 2020 12:01:37 GMT
+            Server: gunicorn/20.0.0
         
             {
                 "_id": "ESPGNU777ORG",
                 "active": true,
-                "biological_sex": "female",
-                "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
+                "dob": "1990-10-04",
                 "education": "tertiary",
                 "ethnicity": "latino",
-                "gender": "female",
+                "gender": "f",
+                "id": "ESPGNU777ORG",
                 "lastname": "Betz",
                 "marital_status": "married",
+                "modification_info": {
+                    "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL",
+                    "timestamp": "2018-11-06 19:24:43.662846",
+                    "user": "ITAPYT999HON"
+                },
                 "name": "Ana",
                 "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
                 "profession": "teacher",
                 "roles": [
-                "end_user"
+                    "end_user"
                 ]
-                
             }
         
         **Retrieve the demographics information globally**::
         
-          $ http --verify no --auth ITAPYT999HON:gnusolidario 
https://localhost:8443/people
+          $ http --verify no --auth ARGBUE111FAV:freedom 
https://federation.gnuhealth.org:8443/people
         
         Yields to::
         
-            HTTP/1.1 200 OK
-            Connection: close
-            Content-Length: 933
-            Content-Type: application/json
-            Date: Fri, 21 Apr 2017 16:31:23 GMT
-            Server: gunicorn/19.7.1
+            HTTP/1.1 200 OK 
+            Access-Control-Allow-Origin: * 
+            Connection: close 
+            Content-Length: 2715 
+            Content-Type: application/json 
+            Date: Mon, 20 Jul 2020 18:03:24 GMT 
+            Server: gunicorn/20.0.0 
+        
+            [ 
+            [ 
+                { 
+                    "active": true, 
+                    "dob": "1984-10-05", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ITAPYT999HON", 
+                    "lastname": "Cordara", 
+                    "marital_status": "married", 
+                    "name": "Cameron", 
+                    "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2", 
+                    "profession": "teacher", 
+                    "roles": [ 
+                        "end_user", 
+                        "health_professional" 
+                    ] 
+                } 
+            ],
+            [ 
+                { 
+                    "creation_info": { 
+                        "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                        "timestamp": "2019-11-20 10:39:21.162731", 
+                        "user": "ITAPYT999HON" 
+                    }, 
+                    "dob": "1999-10-12", 
+                    "gender": "m", 
+                    "id": "DEUMOP095IDI", 
+                    "lastname": "Dillinger", 
+                    "name": "John Doe???", 
+                    "roles": [ 
+                        "end_user" 
+                    ] 
+                } 
+            ],
         
-            [
-                {
-                    "_id": "ITAPYT999HON",
-                    "active": true,
-                    "biological_sex": "female",
-                    "dob": "Fri, 05 Oct 1984 09:00:00 GMT",
-                    "education": "tertiary",
-                    "ethnicity": "latino",
-                    "gender": "female",
-                    "lastname": "Cordara",
-                    "marital_status": "married",
-                    "name": "Cameron",
-                    "password": 
"$2b$12$Y9rX7PoTHRXhTO1H78Tan.8mVmyayGAUIveiYxu2Qeo0ZDRvJQ8/2",
-                    "profession": "teacher",
-                    "roles": [
-                    "end_user",
-                    "health_professional"
-                    ]
-                    
-                },
-                
-                {
-                    "_id": "ESPGNU777ORG",
-                    "active": true,
-                    "biological_sex": "female",
-                    "dob": "Fri, 04 Oct 1985 13:05:00 GMT",
-                    "education": "tertiary",
-                    "ethnicity": "latino",
-                    "gender": "female",
-                    "lastname": "Betz",
-                    "marital_status": "married",
-                    "name": "Ana",
-                    "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW",
-                    "profession": "teacher",
-                    "roles": [
-                    "end_user"
-                    ]
-                    
-                }
-                
-            ]
             
+            [ 
+                { 
+                    "active": true, 
+                    "dob": "2008-10-12", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ARGBUE111FAV", 
+                    "lastname": "Root", 
+                    "marital_status": "married", 
+                    "name": "Admin", 
+                    "password": 
"$2b$12$McKDNgArdHKbUssD1fj64ecpdbJGMIt29ns7DGvqzqIT26W0dtJzi", 
+                    "profession": "System Administrator", 
+                    "roles": [ 
+                        "root" 
+                    ] 
+                } 
+            ], 
+            [ 
+                { 
+                    "_id": "ESPGNU777ORG", 
+                    "active": true, 
+                    "dob": "1990-10-04", 
+                    "education": "tertiary", 
+                    "ethnicity": "latino", 
+                    "gender": "f", 
+                    "id": "ESPGNU777ORG", 
+                    "lastname": "Betz", 
+                    "marital_status": "married", 
+                    "modification_info": { 
+                        "node": "SPAIN-LASPALMAS-GNUSOLIDARIO-GRAL_HOSPITAL", 
+                        "timestamp": "2018-11-06 19:24:43.662846", 
+                        "user": "ITAPYT999HON" 
+                    }, 
+                    "name": "Ana", 
+                    "password": 
"$2b$12$cjrKVGYEKUwCmVDCtEnwcegcrmECTmeBz526AAD/ZqMGPWFpHJ4FW", 
+                    "profession": "teacher", 
+                    "roles": [ 
+                        "end_user" 
+                    ] 
+                } 
+            ], 
+            ]
+        
         
         **Using Python requests**::
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/thalamus.egg-info/requires.txt 
new/thalamus-0.9.13/thalamus.egg-info/requires.txt
--- old/thalamus-0.9.12/thalamus.egg-info/requires.txt  2019-11-20 
09:20:03.000000000 +0100
+++ new/thalamus-0.9.13/thalamus.egg-info/requires.txt  2021-03-03 
20:13:30.000000000 +0100
@@ -1,6 +1,6 @@
+bcrypt
 flask
 flask_httpauth
 flask_restful
 flask_wtf
 psycopg2-binary
-bcrypt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/thalamus-0.9.12/version new/thalamus-0.9.13/version
--- old/thalamus-0.9.12/version 2019-11-20 09:07:57.000000000 +0100
+++ new/thalamus-0.9.13/version 2021-03-03 19:29:38.000000000 +0100
@@ -1 +1 @@
-0.9.12
+0.9.13

Reply via email to