From bd6dd69524ff0988b10fa1c180381f21e97de3cc Mon Sep 17 00:00:00 2001
From: Christian Dresen <c.dresen@fh-muenster.de>
Date: Fri, 9 Sep 2016 17:22:17 +0200
Subject: [PATCH] no message

---
 www/Dockerfile                                |   4 +-
 www/misc/entrypoint.sh                        |   2 +-
 www/nginx/nginx_warpinfra.conf                |  17 ++-
 www/nginx/warpinfra.crt                       | 116 +++++++++++----
 www/nginx/warpinfra.key                       | 135 +++++++++++-------
 www/run_dev.sh                                |   4 +-
 www/run_prod.sh                               |   1 +
 www/web/data/warpzone.db                      |   0
 www/web/warpauth/migrations/0001_initial.py   |  18 +--
 .../migrations/0002_auto_20160821_1613.py     |  56 ++++++++
 .../migrations/0002_ldapuser_card_id.py       |  22 +++
 www/web/warpauth/models.py                    |   4 +-
 www/web/warpfood/migrations/0001_initial.py   |   2 +-
 www/web/warpmain/migrations/0001_initial.py   |   2 +-
 www/web/warppay/admin.py                      |  16 +++
 www/web/warppay/migrations/0001_initial.py    |   3 +-
 .../migrations/0002_auto_20160821_1701.py     |  44 ++++++
 .../migrations/0002_usercredit_card_id.py     |  21 +++
 .../migrations/0003_auto_20160821_1706.py     |  28 ++++
 .../migrations/0004_auto_20160909_1401.py     |  20 +++
 www/web/warppay/models.py                     |  31 ++--
 www/web/warppay/urls.py                       |   4 +
 www/web/warppay/views.py                      |  83 ++++++++---
 www/web/warpzone.db                           | Bin 76800 -> 79872 bytes
 24 files changed, 507 insertions(+), 126 deletions(-)
 create mode 100644 www/web/data/warpzone.db
 create mode 100644 www/web/warpauth/migrations/0002_auto_20160821_1613.py
 create mode 100644 www/web/warpauth/migrations/0002_ldapuser_card_id.py
 create mode 100644 www/web/warppay/migrations/0002_auto_20160821_1701.py
 create mode 100644 www/web/warppay/migrations/0002_usercredit_card_id.py
 create mode 100644 www/web/warppay/migrations/0003_auto_20160821_1706.py
 create mode 100644 www/web/warppay/migrations/0004_auto_20160909_1401.py

diff --git a/www/Dockerfile b/www/Dockerfile
index b912afc..d430958 100644
--- a/www/Dockerfile
+++ b/www/Dockerfile
@@ -34,13 +34,13 @@ RUN rm /etc/nginx/sites-enabled/default
 
 RUN mkdir /opt/socket/
 
-COPY misc/ldapdb_base.py /usr/local/lib/python2.7/dist-packages/ldapdb/backends/ldap/base.py
+COPY misc/ldapdb_base.py /usr/local/lib/python3.4/dist-packages/ldapdb/backends/ldap/base.py
 COPY misc/entrypoint.sh /opt/entrypoint.sh
 
 ADD web /opt/warpinfra/
 ADD nginx /opt/nginx
 
-EXPOSE 8000
+EXPOSE 8000 443 80
 
 VOLUME ["/opt/nginx", "/opt/warpinfra"]
 
diff --git a/www/misc/entrypoint.sh b/www/misc/entrypoint.sh
index ac1f3e3..36f0bbd 100644
--- a/www/misc/entrypoint.sh
+++ b/www/misc/entrypoint.sh
@@ -5,7 +5,7 @@ cd /opt/warpinfra;
 python3 manage.py makemigrations
 python3 manage.py migrate
 python3 manage.py collectstatic --noinput
-
+cp -r /opt/warpinfra/static /opt/socket/
 uwsgi --ini /opt/nginx/uwsgi.ini --py-autoreload 1
 
 bash
diff --git a/www/nginx/nginx_warpinfra.conf b/www/nginx/nginx_warpinfra.conf
index 2c993ba..33bccbd 100644
--- a/www/nginx/nginx_warpinfra.conf
+++ b/www/nginx/nginx_warpinfra.conf
@@ -4,7 +4,22 @@ upstream django {
 
 server {
     listen      80;
-    return 301 https://$host$request_uri;
+    server_name _;
+    charset     utf-8;
+
+    client_max_body_size 100M;   # adjust to taste
+
+    location /static {
+        alias /opt/warpinfra/static; # your Django project's static files - amend as required
+    }
+
+    # Finally, send all non-media requests to the Django server.
+    location / {
+        uwsgi_pass  django;
+        include     /opt/nginx/uwsgi_params; # the uwsgi_params file you installed
+    }
+
+#    return 301 https://$host$request_uri;
 }
 
 # configuration of the server
diff --git a/www/nginx/warpinfra.crt b/www/nginx/warpinfra.crt
index 57cf97f..f50c90d 100644
--- a/www/nginx/warpinfra.crt
+++ b/www/nginx/warpinfra.crt
@@ -1,33 +1,87 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+s9A9vnnfhuMh
+7TJQQ+/pEAY2cQomr2zQqZbkcbZe+7vSf9BnXZbW9WBq932YQI5LT9aopkJrUgGM
+BdifjwXG5umIio4Jdp/HduBv7cg5S7aEABsFgNJ7eIRZsQ5J6Ho1ce1HhqcM8eEe
+W/IiKBUxfzBkugZ59wk7v6SMcpGNiDKEt9osHEPVKC+2sKII6dA72iLnZg3UeQHa
+2ixL4u92Dmvr3mq7Il4wGydvEMLXFYg1L20Qnvy3uOC0MpYG9iz6e5OK+FH4ytCE
+vBkOsyWZ5v+//ufThDlQPuIygPXuYUq+cZaIeYpXmVaGtf2gV0XQmvypna6EcsHp
+xnEP0tZNAgMBAAECggEAWfO1OTqcgAw/HOSmg+fXxUZyt8FQOXkrya0E6NKeZGU3
+bg4t/mPN3600gqAk1Ok2dV2+ciSiVb8DzcmAKZsr7WtEIszAPMSAj3SKXyF4/VWy
+TMdD96+RGP5651e11rTa2FTZyJBCQb/iIRDbwLLJdGR7Ljf1EBiveUhnVHxCHdCc
+/HOuGQnEJR1zOO8llTp36XN457ufqWWKSpS507gBmKdQiJDIooclaf71CIkJQBjh
+j04O74RlTpTFzHyg/vzn5VDllwokgAJ3g9PgunBmHqCTQCF5chkkBKaubtKa2hx0
+JsXuTS8Zf6TBRNlUXxPC4SwkuUMdRFIcCAlSF8jK3QKBgQDkbtfGC8PAoYTIO6pK
+tgRWSkdMkYG6UBoiLpH8qh7KDXT+CRcYdZNsDrH97VxaZlPUccL3Zrw68UVd50St
+Vfdke/BD0lkmzjACou4Ebwmp4ZupEE8RghKP7MoWlNLqzLs4T60UzQHMyNIUUxkT
+f6hWnuUBxasKkx4a+t2HWvXUrwKBgQDVt1SVcPcjr6VbFqs51LrzX4NU6d/b/il+
+uQS7QENzuCzVviGWAH59yQeVUSBB1xZweennIRnHhcpFYlqKA69VUwkyQb7uZZ4Y
+iRvlOAdbBE156LsUE0vU6rFDyCNGvhz5ClKt+nXWoJscl1kY3S5qyPGhkrwBFlQT
+594niKq7wwKBgQCt5Pt5lkckg1CzpUgTq9BNaCoyzan2DTh3wP/9WfwqUGg5Yu4j
+/o2FewJgjar6Xl9+oEONVrYAIN9vhrivQ3wbEIZs+tpHQjsmJqYO1gCDRG3dG781
+UtGSou2Mlyqg982mJnFaHl46aL4UHtY+E7YwirFG0hVM7YXDgCnX+pSdnQKBgGnj
+TrZIZTq6MSyDe8zIeORSg4iT5AVk1XxjAVQhkAoKy7QPYyamEgYSj35M1rWocwbB
+cMHCpbo0sLZV99P/5WRaIulSp94IXR9892RHsWVIKXbod6CHuv/AVJnn1IqdcU92
+7OYkfTQdGR0+Y7etBu2DqCzMvfev73J5ZJmj3ivvAoGBAIz13UZrQoj7SdOjUZkJ
+xGVjQKZbxJmEPCDXRoEjkPAmNCYiEtgMSD2xYuaSly1qyKwEwaevDzGBVO9Gf9QN
+9Lmb4E9OKVehGpdPYT2+MPKO4i0dXfD5w3CP7SXE6zhzInmX5+qEcdAqVemz8QI0
+b2XE2w6nht6kQcMj7MrdCphv
+-----END PRIVATE KEY-----
+
 -----BEGIN CERTIFICATE-----
-MIIFrTCCA5WgAwIBAgIJAKzK6RrFSz83MA0GCSqGSIb3DQEBCwUAMG0xCzAJBgNV
-BAYTAkRFMQwwCgYDVQQIDANOUlcxETAPBgNVBAcMCE11ZW5zdGVyMRIwEAYDVQQK
-DAlJVFNlY1RlYW0xEzARBgNVBAsMCkZsYWdIdW50ZXIxFDASBgNVBAMMC2ZsYWcu
-aHVudGVyMB4XDTE1MTEyMDE5MTQ1OVoXDTE2MTExOTE5MTQ1OVowbTELMAkGA1UE
-BhMCREUxDDAKBgNVBAgMA05SVzERMA8GA1UEBwwITXVlbnN0ZXIxEjAQBgNVBAoM
-CUlUU2VjVGVhbTETMBEGA1UECwwKRmxhZ0h1bnRlcjEUMBIGA1UEAwwLZmxhZy5o
-dW50ZXIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC7toPOwQ1Xcqwk
-VJItQC8wifoGeNk/E0k52XYVhvxXsZZI90n3CBp4LEIUMB6tPBwZ/mpI83hUu29f
-yWkD1iexWFQF5uJJr4IlAjKjznYuvi7EzbNAQsFTmOYRvmTSVvnONx1PpZFRGEt8
-d4AmeztCMtk9JCV45xPeh7T00mxq7okOFsfrIlKfi7q0N5X1neMK4hgOuRqR+TE3
-MJvcsCKzIi/g1hvrly48OZqhnoBeQZHxbuT2i+jyl56sBjHqRswFxxBOwifEBNsP
-V27Q9LWAi6tF1+RU6YYtfD4/en9sLEZ9y9U+Ch9kL82EaScIh234Sxb7VevAdJ3K
-b+sL3Vum3JaOwejhTbzMtl2JkTy7knR2PUFW4ZA85MvE6/IChFoYSHVM/rsbUESn
-nu08qAQ7AF2Yj/+sPCqc1BUEXxO6qYFeX+yXx4Fbl29xu3d5evbc2CHjVqGuGRyv
-2V7XkuUHhvLmYV8AVUFHp1yLxhEZsMl4eSoPjVnNmY/WoljJeNjC7XmHwllsvqJt
-59meh7FkD28DPducKnjfsKElqbc5pjeVi24302nHTS41eExalgHCd07j2sQVjXgF
-C3BUP2Jl+tU2QV5/jRH2GCLMkhEwP/lPdK5usS9jXhJo0sb56M1ak4ECfavrxHHh
-TSmgD9IaqP0ChOVIZ04DuxYxX2MURQIDAQABo1AwTjAdBgNVHQ4EFgQUC/Jkv7Vf
-f/VAeY8zrBqvyWe+L4cwHwYDVR0jBBgwFoAUC/Jkv7Vff/VAeY8zrBqvyWe+L4cw
-DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAeTtgmsIFI6LgxbyAIc/8
-dZXmP9DKXZkv17UEAKoJC/d+IOqDogXoeRhbo2cLmIXCE5cmhp+xsXZnxke4Oq39
-az6eBlcwaPUUTlzP5MiIqDpzbhi6sjQhp5FmH2/RtFkVzjpNm2NP+7IW1lAxx3is
-qxXBCVXYXmiHL6rW5BwNrlGDqwUhFDVZJL4QIBENqwMC7qTubYiukBdaqWz8uTYs
-WFOo73fYqG/SNbFifq78czTRoXTTr085Yxnprr4whuqTPpmBd42IUzOxRHF5ICPX
-316S6X3b65mTzzz15p1KquUe+VsULnUZTtOOeyIqpm8VWSu4EoKK0c2w8bZkgImR
-ttAMRnA4S00ZuhQ1CnJgMX/54krJWdswJH7O+fTsu7A7jy2PhADbyhPx61pVyH2H
-zYm+7RPlvGgdkqvdyO6EeZN1RRIPkyUb+6bbCwHPIDRc+DXh5dq4w0wN7vctMMri
-eo+OrxK97O4egmg67J3XCYBCmPsnH0vaV/UTOgmyeo7Y8NqMulUOCVz1PhidW0r2
-M7dRB7958G6Z1tuuFXr0Y+88RDyTHdu9XqCLHjLAjF2PIqhPHZ59KnHVmb4bWICK
-4D3rdOS0woeiXCxUQxekBh8ZMBIzyeUONrkYykBwV5sZrMZt26GGMlNyJ7uYcFzW
-MsRX8eO4RytlNdVSGVSrLpQ=
+MIIE/jCCA+agAwIBAgISA1hyjstoi3F5Iclnmu5EQMScMA0GCSqGSIb3DQEBCwUA
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjA4MjgxNDI5MDBaFw0x
+NjExMjYxNDI5MDBaMBgxFjAUBgNVBAMTDWRldi5keWhvc3QuZGUwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+s9A9vnnfhuMh7TJQQ+/pEAY2cQomr2zQ
+qZbkcbZe+7vSf9BnXZbW9WBq932YQI5LT9aopkJrUgGMBdifjwXG5umIio4Jdp/H
+duBv7cg5S7aEABsFgNJ7eIRZsQ5J6Ho1ce1HhqcM8eEeW/IiKBUxfzBkugZ59wk7
+v6SMcpGNiDKEt9osHEPVKC+2sKII6dA72iLnZg3UeQHa2ixL4u92Dmvr3mq7Il4w
+GydvEMLXFYg1L20Qnvy3uOC0MpYG9iz6e5OK+FH4ytCEvBkOsyWZ5v+//ufThDlQ
+PuIygPXuYUq+cZaIeYpXmVaGtf2gV0XQmvypna6EcsHpxnEP0tZNAgMBAAGjggIO
+MIICCjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
+BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFHahdg/WaDq0yPz59/SZOwb9HmLX
+MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUFBwEBBGQw
+YjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9y
+Zy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5v
+cmcvMBgGA1UdEQQRMA+CDWRldi5keWhvc3QuZGUwgf4GA1UdIASB9jCB8zAIBgZn
+gQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRwOi8vY3Bz
+LmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRpZmlj
+YXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBh
+bmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGlj
+eSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzAN
+BgkqhkiG9w0BAQsFAAOCAQEAl598A9BClTRIh84bzUTSSGu8nym9IOpl5and/gCX
+IsB1w66ZhJDcJC21mXkQWRSSysenwX0zayRaNs2KMZviyr32RTTfNPJHXFROYiNl
+G0iQodNvEhkF05/QEPS2DvFWqwU9nkxZ9byzzvciwFVHh1RqDzmGUqQTyu6pAqBt
+UZIjFulDL/zjLduIz9326hPGv/9qiEbumPpH7WTxUesaBrXXgrCSDkrXrVwk5V+b
+hGU5s/gEsrAxqQgFVqhrrnc8fK40kcqF45i5K2mrhFMSNtEuI7gwrKbs+vulZpJY
+TM2a4Gtibkew5XwpaC7aED6QLNux9jQdQ3lqsaSLj4Y9dQ==
 -----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
+
diff --git a/www/nginx/warpinfra.key b/www/nginx/warpinfra.key
index fb31d8d..f50c90d 100644
--- a/www/nginx/warpinfra.key
+++ b/www/nginx/warpinfra.key
@@ -1,52 +1,87 @@
 -----BEGIN PRIVATE KEY-----
-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
-su7ZYG7K5L+RRjrWZagNh8X2s6qeaA==
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+s9A9vnnfhuMh
+7TJQQ+/pEAY2cQomr2zQqZbkcbZe+7vSf9BnXZbW9WBq932YQI5LT9aopkJrUgGM
+BdifjwXG5umIio4Jdp/HduBv7cg5S7aEABsFgNJ7eIRZsQ5J6Ho1ce1HhqcM8eEe
+W/IiKBUxfzBkugZ59wk7v6SMcpGNiDKEt9osHEPVKC+2sKII6dA72iLnZg3UeQHa
+2ixL4u92Dmvr3mq7Il4wGydvEMLXFYg1L20Qnvy3uOC0MpYG9iz6e5OK+FH4ytCE
+vBkOsyWZ5v+//ufThDlQPuIygPXuYUq+cZaIeYpXmVaGtf2gV0XQmvypna6EcsHp
+xnEP0tZNAgMBAAECggEAWfO1OTqcgAw/HOSmg+fXxUZyt8FQOXkrya0E6NKeZGU3
+bg4t/mPN3600gqAk1Ok2dV2+ciSiVb8DzcmAKZsr7WtEIszAPMSAj3SKXyF4/VWy
+TMdD96+RGP5651e11rTa2FTZyJBCQb/iIRDbwLLJdGR7Ljf1EBiveUhnVHxCHdCc
+/HOuGQnEJR1zOO8llTp36XN457ufqWWKSpS507gBmKdQiJDIooclaf71CIkJQBjh
+j04O74RlTpTFzHyg/vzn5VDllwokgAJ3g9PgunBmHqCTQCF5chkkBKaubtKa2hx0
+JsXuTS8Zf6TBRNlUXxPC4SwkuUMdRFIcCAlSF8jK3QKBgQDkbtfGC8PAoYTIO6pK
+tgRWSkdMkYG6UBoiLpH8qh7KDXT+CRcYdZNsDrH97VxaZlPUccL3Zrw68UVd50St
+Vfdke/BD0lkmzjACou4Ebwmp4ZupEE8RghKP7MoWlNLqzLs4T60UzQHMyNIUUxkT
+f6hWnuUBxasKkx4a+t2HWvXUrwKBgQDVt1SVcPcjr6VbFqs51LrzX4NU6d/b/il+
+uQS7QENzuCzVviGWAH59yQeVUSBB1xZweennIRnHhcpFYlqKA69VUwkyQb7uZZ4Y
+iRvlOAdbBE156LsUE0vU6rFDyCNGvhz5ClKt+nXWoJscl1kY3S5qyPGhkrwBFlQT
+594niKq7wwKBgQCt5Pt5lkckg1CzpUgTq9BNaCoyzan2DTh3wP/9WfwqUGg5Yu4j
+/o2FewJgjar6Xl9+oEONVrYAIN9vhrivQ3wbEIZs+tpHQjsmJqYO1gCDRG3dG781
+UtGSou2Mlyqg982mJnFaHl46aL4UHtY+E7YwirFG0hVM7YXDgCnX+pSdnQKBgGnj
+TrZIZTq6MSyDe8zIeORSg4iT5AVk1XxjAVQhkAoKy7QPYyamEgYSj35M1rWocwbB
+cMHCpbo0sLZV99P/5WRaIulSp94IXR9892RHsWVIKXbod6CHuv/AVJnn1IqdcU92
+7OYkfTQdGR0+Y7etBu2DqCzMvfev73J5ZJmj3ivvAoGBAIz13UZrQoj7SdOjUZkJ
+xGVjQKZbxJmEPCDXRoEjkPAmNCYiEtgMSD2xYuaSly1qyKwEwaevDzGBVO9Gf9QN
+9Lmb4E9OKVehGpdPYT2+MPKO4i0dXfD5w3CP7SXE6zhzInmX5+qEcdAqVemz8QI0
+b2XE2w6nht6kQcMj7MrdCphv
 -----END PRIVATE KEY-----
+
+-----BEGIN CERTIFICATE-----
+MIIE/jCCA+agAwIBAgISA1hyjstoi3F5Iclnmu5EQMScMA0GCSqGSIb3DQEBCwUA
+MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
+ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0xNjA4MjgxNDI5MDBaFw0x
+NjExMjYxNDI5MDBaMBgxFjAUBgNVBAMTDWRldi5keWhvc3QuZGUwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+s9A9vnnfhuMh7TJQQ+/pEAY2cQomr2zQ
+qZbkcbZe+7vSf9BnXZbW9WBq932YQI5LT9aopkJrUgGMBdifjwXG5umIio4Jdp/H
+duBv7cg5S7aEABsFgNJ7eIRZsQ5J6Ho1ce1HhqcM8eEeW/IiKBUxfzBkugZ59wk7
+v6SMcpGNiDKEt9osHEPVKC+2sKII6dA72iLnZg3UeQHa2ixL4u92Dmvr3mq7Il4w
+GydvEMLXFYg1L20Qnvy3uOC0MpYG9iz6e5OK+FH4ytCEvBkOsyWZ5v+//ufThDlQ
+PuIygPXuYUq+cZaIeYpXmVaGtf2gV0XQmvypna6EcsHpxnEP0tZNAgMBAAGjggIO
+MIICCjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF
+BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFHahdg/WaDq0yPz59/SZOwb9HmLX
+MB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMHAGCCsGAQUFBwEBBGQw
+YjAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNyeXB0Lm9y
+Zy8wLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5v
+cmcvMBgGA1UdEQQRMA+CDWRldi5keWhvc3QuZGUwgf4GA1UdIASB9jCB8zAIBgZn
+gQwBAgEwgeYGCysGAQQBgt8TAQEBMIHWMCYGCCsGAQUFBwIBFhpodHRwOi8vY3Bz
+LmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtUaGlzIENlcnRpZmlj
+YXRlIG1heSBvbmx5IGJlIHJlbGllZCB1cG9uIGJ5IFJlbHlpbmcgUGFydGllcyBh
+bmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRpZmljYXRlIFBvbGlj
+eSBmb3VuZCBhdCBodHRwczovL2xldHNlbmNyeXB0Lm9yZy9yZXBvc2l0b3J5LzAN
+BgkqhkiG9w0BAQsFAAOCAQEAl598A9BClTRIh84bzUTSSGu8nym9IOpl5and/gCX
+IsB1w66ZhJDcJC21mXkQWRSSysenwX0zayRaNs2KMZviyr32RTTfNPJHXFROYiNl
+G0iQodNvEhkF05/QEPS2DvFWqwU9nkxZ9byzzvciwFVHh1RqDzmGUqQTyu6pAqBt
+UZIjFulDL/zjLduIz9326hPGv/9qiEbumPpH7WTxUesaBrXXgrCSDkrXrVwk5V+b
+hGU5s/gEsrAxqQgFVqhrrnc8fK40kcqF45i5K2mrhFMSNtEuI7gwrKbs+vulZpJY
+TM2a4Gtibkew5XwpaC7aED6QLNux9jQdQ3lqsaSLj4Y9dQ==
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
+SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
+GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
+q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
+SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
+Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
+a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
+/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
+AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
+CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
+bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
+c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
+VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
+ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
+MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
+Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
+AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
+uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
+wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
+X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
+PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
+KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
+-----END CERTIFICATE-----
+
diff --git a/www/run_dev.sh b/www/run_dev.sh
index b32520a..476fcd0 100644
--- a/www/run_dev.sh
+++ b/www/run_dev.sh
@@ -6,10 +6,10 @@ docker rm warpinfra
 
 docker run \
 	-v $SCRIPTPATH/web:/opt/warpinfra \
-        -v $SCRIPTPATH/nginx:/opt/nginx \
+    -v $SCRIPTPATH/nginx:/opt/nginx \
 	-v $SCRIPTPATH/conf/config.example.ini:/etc/warpinfra/config.ini \
 	--link ldap-service:ldap \
 	--name warpinfra \
-	-p 8000:443 \
+	-p 8000:80 \
 	-itd \
 	warpinfra
diff --git a/www/run_prod.sh b/www/run_prod.sh
index d9cb938..ac4e649 100644
--- a/www/run_prod.sh
+++ b/www/run_prod.sh
@@ -9,6 +9,7 @@ docker run \
 	--link ldap-service:ldap \
 	--name warpinfra \
     --volume /tmp/warpinfra:/opt/socket \
+    --volume /opt/warpinfra/data:/opt/database/
 	-p 8000:443 \
 	-itd \
 	warpinfra
diff --git a/www/web/data/warpzone.db b/www/web/data/warpzone.db
new file mode 100644
index 0000000..e69de29
diff --git a/www/web/warpauth/migrations/0001_initial.py b/www/web/warpauth/migrations/0001_initial.py
index d9bbae0..495e7e8 100644
--- a/www/web/warpauth/migrations/0001_initial.py
+++ b/www/web/warpauth/migrations/0001_initial.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-08-18 15:07
+# Generated by Django 1.9 on 2016-08-21 16:21
 from __future__ import unicode_literals
 
 from django.db import migrations, models
@@ -18,9 +18,9 @@ class Migration(migrations.Migration):
             name='LdapGroup',
             fields=[
                 ('dn', models.CharField(max_length=200)),
-                ('gid', ldapdb.models.fields.IntegerField(db_column=b'gidNumber', unique=True)),
-                ('name', ldapdb.models.fields.CharField(db_column=b'cn', max_length=200, primary_key=True, serialize=False)),
-                ('members', ldapdb.models.fields.ListField(db_column=b'memberUid')),
+                ('gid', ldapdb.models.fields.IntegerField(db_column='gidNumber', unique=True)),
+                ('name', ldapdb.models.fields.CharField(db_column='cn', max_length=200, primary_key=True, serialize=False)),
+                ('members', ldapdb.models.fields.ListField(db_column='memberUid')),
             ],
             options={
                 'abstract': False,
@@ -30,11 +30,11 @@ class Migration(migrations.Migration):
             name='LdapUser',
             fields=[
                 ('dn', models.CharField(max_length=200)),
-                ('uid', ldapdb.models.fields.CharField(db_column=b'uid', max_length=200, primary_key=True, serialize=False, unique=True)),
-                ('first_name', ldapdb.models.fields.CharField(db_column=b'givenName', max_length=200)),
-                ('last_name', ldapdb.models.fields.CharField(db_column=b'sn', max_length=200)),
-                ('email', ldapdb.models.fields.CharField(db_column=b'description', max_length=200)),
-                ('cn', ldapdb.models.fields.CharField(db_column=b'cn', max_length=200)),
+                ('uid', ldapdb.models.fields.CharField(db_column='uid', max_length=200, primary_key=True, serialize=False, unique=True)),
+                ('first_name', ldapdb.models.fields.CharField(db_column='givenName', max_length=200)),
+                ('last_name', ldapdb.models.fields.CharField(db_column='sn', max_length=200)),
+                ('email', ldapdb.models.fields.CharField(db_column='mail', max_length=200)),
+                ('cn', ldapdb.models.fields.CharField(db_column='cn', max_length=200)),
             ],
             options={
                 'abstract': False,
diff --git a/www/web/warpauth/migrations/0002_auto_20160821_1613.py b/www/web/warpauth/migrations/0002_auto_20160821_1613.py
new file mode 100644
index 0000000..e83f519
--- /dev/null
+++ b/www/web/warpauth/migrations/0002_auto_20160821_1613.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-08-21 16:13
+from __future__ import unicode_literals
+
+from django.db import migrations
+import ldapdb.models.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warpauth', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='ldapgroup',
+            name='gid',
+            field=ldapdb.models.fields.IntegerField(db_column='gidNumber', unique=True),
+        ),
+        migrations.AlterField(
+            model_name='ldapgroup',
+            name='members',
+            field=ldapdb.models.fields.ListField(db_column='memberUid'),
+        ),
+        migrations.AlterField(
+            model_name='ldapgroup',
+            name='name',
+            field=ldapdb.models.fields.CharField(db_column='cn', max_length=200, primary_key=True, serialize=False),
+        ),
+        migrations.AlterField(
+            model_name='ldapuser',
+            name='cn',
+            field=ldapdb.models.fields.CharField(db_column='cn', max_length=200),
+        ),
+        migrations.AlterField(
+            model_name='ldapuser',
+            name='email',
+            field=ldapdb.models.fields.CharField(db_column='mail', max_length=200),
+        ),
+        migrations.AlterField(
+            model_name='ldapuser',
+            name='first_name',
+            field=ldapdb.models.fields.CharField(db_column='givenName', max_length=200),
+        ),
+        migrations.AlterField(
+            model_name='ldapuser',
+            name='last_name',
+            field=ldapdb.models.fields.CharField(db_column='sn', max_length=200),
+        ),
+        migrations.AlterField(
+            model_name='ldapuser',
+            name='uid',
+            field=ldapdb.models.fields.CharField(db_column='uid', max_length=200, primary_key=True, serialize=False, unique=True),
+        ),
+    ]
diff --git a/www/web/warpauth/migrations/0002_ldapuser_card_id.py b/www/web/warpauth/migrations/0002_ldapuser_card_id.py
new file mode 100644
index 0000000..95cb90c
--- /dev/null
+++ b/www/web/warpauth/migrations/0002_ldapuser_card_id.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-08-21 16:52
+from __future__ import unicode_literals
+
+from django.db import migrations
+import ldapdb.models.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warpauth', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='ldapuser',
+            name='card_id',
+            field=ldapdb.models.fields.CharField(db_column='pager', default=0, max_length=200),
+            preserve_default=False,
+        ),
+    ]
diff --git a/www/web/warpauth/models.py b/www/web/warpauth/models.py
index 3f4bae7..e783a92 100644
--- a/www/web/warpauth/models.py
+++ b/www/web/warpauth/models.py
@@ -22,7 +22,7 @@ class LdapUser(ldapdb.models.Model):
     last_name = CharField(db_column='sn', max_length=200)
     email = CharField(db_column='mail', max_length=200)
     cn = CharField(db_column='cn', max_length=200)
-
+    card_id = CharField(db_column='pager', max_length=200)
 
     def __str__(self):
         return self.uid
@@ -34,7 +34,7 @@ class LdapUser(ldapdb.models.Model):
 class LdapUserForm(ModelForm):
     class Meta:
         model = LdapUser
-        fields = ['first_name', 'last_name', 'email']
+        fields = ['first_name', 'last_name', 'email','card_id']
 
 
 class LdapGroup(ldapdb.models.Model):
diff --git a/www/web/warpfood/migrations/0001_initial.py b/www/web/warpfood/migrations/0001_initial.py
index b058e2f..0a5a045 100644
--- a/www/web/warpfood/migrations/0001_initial.py
+++ b/www/web/warpfood/migrations/0001_initial.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-08-18 15:07
+# Generated by Django 1.9 on 2016-08-21 16:20
 from __future__ import unicode_literals
 
 from django.db import migrations, models
diff --git a/www/web/warpmain/migrations/0001_initial.py b/www/web/warpmain/migrations/0001_initial.py
index e9f0080..110b564 100644
--- a/www/web/warpmain/migrations/0001_initial.py
+++ b/www/web/warpmain/migrations/0001_initial.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-08-18 15:07
+# Generated by Django 1.9 on 2016-08-21 16:27
 from __future__ import unicode_literals
 
 from django.db import migrations, models
diff --git a/www/web/warppay/admin.py b/www/web/warppay/admin.py
index e69de29..5f28e74 100644
--- a/www/web/warppay/admin.py
+++ b/www/web/warppay/admin.py
@@ -0,0 +1,16 @@
+from django.contrib import admin
+from warppay.models import *
+
+# Register your models here.
+
+@admin.register(ProductCategory)
+class ProductCategoryAdmin(admin.ModelAdmin):
+        pass
+
+@admin.register(Product)
+class ProductAdmin(admin.ModelAdmin):
+        pass
+
+@admin.register(UserCredit)
+class UserCreditAdmin(admin.ModelAdmin):
+        pass
\ No newline at end of file
diff --git a/www/web/warppay/migrations/0001_initial.py b/www/web/warppay/migrations/0001_initial.py
index 8bb050b..03b54ba 100644
--- a/www/web/warppay/migrations/0001_initial.py
+++ b/www/web/warppay/migrations/0001_initial.py
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2016-08-18 15:07
+# Generated by Django 1.9 on 2016-08-21 16:21
 from __future__ import unicode_literals
 
 from django.db import migrations, models
@@ -28,6 +28,7 @@ class Migration(migrations.Migration):
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                 ('uid', models.CharField(max_length=100, unique=True)),
+                ('card_id', models.IntegerField()),
                 ('credit', models.FloatField()),
             ],
         ),
diff --git a/www/web/warppay/migrations/0002_auto_20160821_1701.py b/www/web/warppay/migrations/0002_auto_20160821_1701.py
new file mode 100644
index 0000000..e8d2e68
--- /dev/null
+++ b/www/web/warppay/migrations/0002_auto_20160821_1701.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-08-21 17:01
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warppay', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='product',
+            old_name='user',
+            new_name='name',
+        ),
+        migrations.RemoveField(
+            model_name='product',
+            name='created',
+        ),
+        migrations.RemoveField(
+            model_name='product',
+            name='message',
+        ),
+        migrations.RemoveField(
+            model_name='product',
+            name='title',
+        ),
+        migrations.AddField(
+            model_name='product',
+            name='count',
+            field=models.IntegerField(default=0),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='product',
+            name='price',
+            field=models.FloatField(default=0),
+            preserve_default=False,
+        ),
+    ]
diff --git a/www/web/warppay/migrations/0002_usercredit_card_id.py b/www/web/warppay/migrations/0002_usercredit_card_id.py
new file mode 100644
index 0000000..bcb14cd
--- /dev/null
+++ b/www/web/warppay/migrations/0002_usercredit_card_id.py
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-08-21 16:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warppay', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='usercredit',
+            name='card_id',
+            field=models.IntegerField(default=0),
+            preserve_default=False,
+        ),
+    ]
diff --git a/www/web/warppay/migrations/0003_auto_20160821_1706.py b/www/web/warppay/migrations/0003_auto_20160821_1706.py
new file mode 100644
index 0000000..d834e1b
--- /dev/null
+++ b/www/web/warppay/migrations/0003_auto_20160821_1706.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-08-21 17:06
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warppay', '0002_auto_20160821_1701'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='ProductCategory',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=100, unique=True)),
+            ],
+        ),
+        migrations.AddField(
+            model_name='product',
+            name='category',
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='warppay.ProductCategory'),
+        ),
+    ]
diff --git a/www/web/warppay/migrations/0004_auto_20160909_1401.py b/www/web/warppay/migrations/0004_auto_20160909_1401.py
new file mode 100644
index 0000000..4d8597b
--- /dev/null
+++ b/www/web/warppay/migrations/0004_auto_20160909_1401.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-09-09 14:01
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('warppay', '0003_auto_20160821_1706'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='usercredit',
+            name='card_id',
+            field=models.CharField(max_length=10, unique=True),
+        ),
+    ]
diff --git a/www/web/warppay/models.py b/www/web/warppay/models.py
index c462cfa..edda802 100644
--- a/www/web/warppay/models.py
+++ b/www/web/warppay/models.py
@@ -4,22 +4,35 @@ from django.db import models
 from rest_framework import routers, serializers, viewsets
 from warpauth.models import LdapUser
 
-
+class ProductCategory(models.Model):
+    name = models.CharField(max_length=100, unique=True)
+    def __str__(self):
+        return self.name
+        
 class Product(models.Model):
-    user = models.CharField(max_length=100, null=True)
-    title = models.CharField(max_length=100)
-    message = models.TextField()
-    created = models.DateTimeField(auto_now_add=True)
+    name = models.CharField(max_length=100, null=True)
+    price = models.FloatField()
+    category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE, null=True)
+    count = models.IntegerField()
 
     def __str__(self):
-        return self.title
+        return self.name
+
+class ProductSerializer(serializers.ModelSerializer):
+    category = serializers.StringRelatedField()
+    class Meta:
+        model = Product
+        fields = ['id', 'name', 'price', 'category', 'count']
 
+        
 class UserCredit(models.Model):
     uid = models.CharField(max_length=100,unique=True)
+    card_id = models.CharField(max_length=10, unique=True)
     credit = models.FloatField()
+    def __str__(self):
+        return self.uid
 
-
-class UserCreditSerializer(serializers.HyperlinkedModelSerializer):
+class UserCreditSerializer(serializers.ModelSerializer):
     class Meta:
         model = UserCredit
-        fields = ['uid', 'credit']
+        fields = ['uid', 'card_id', 'credit']
diff --git a/www/web/warppay/urls.py b/www/web/warppay/urls.py
index 157ac62..ac022ce 100644
--- a/www/web/warppay/urls.py
+++ b/www/web/warppay/urls.py
@@ -4,4 +4,8 @@ from warppay import views
 urlpatterns = [
     #url(r'^api/', include(router.urls)),
     url(r'^api/users/$', views.user_list),
+    url(r'^api/users/(?P<user_id>\w+)/$', views.user_list),
+    url(r'^api/products/$', views.product_list),
+    url(r'^api/gen_token/$', views.gen_token),
+
 ]
diff --git a/www/web/warppay/views.py b/www/web/warppay/views.py
index 42db93a..2cae82a 100644
--- a/www/web/warppay/views.py
+++ b/www/web/warppay/views.py
@@ -1,41 +1,92 @@
 from django.db import IntegrityError
 from warpauth.models import LdapUser
-from warppay.models import UserCredit, UserCreditSerializer
+from warppay.models import UserCredit, UserCreditSerializer, Product, ProductSerializer
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
 from rest_framework.authentication import TokenAuthentication
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.decorators import authentication_classes, permission_classes
+from rest_framework.authtoken.models import Token
+from django.contrib.auth.models import User
+from rest_framework import status
 
-# from rest_framework.authtoken.models import Token
-# token = Token.objects.create(user=request.user)
 # logging.getLogger('main').info(token.key)
 
-@api_view(['GET', 'POST', 'PUT'])
-@authentication_classes((TokenAuthentication,))
-@permission_classes((IsAuthenticated,))
-def user_list(request):
+@api_view(['GET', 'PUT'])
+#@authentication_classes((TokenAuthentication,))
+#@permission_classes((IsAuthenticated,))
+def product_list(request):
     if request.method == 'GET':
-        sync_users()
-        users = UserCredit.objects.all()
-        serializer = UserCreditSerializer(users, many=True)
+        products = Product.objects.all()
+        serializer = ProductSerializer(products,context={'request': request}, many=True)
         return Response(serializer.data)
-    elif request.method == 'POST':
-
+    elif request.method == 'PUT':
         return Response()
+    return Response()
+
+
+@api_view(['GET'])
+def gen_token(request):
+    if request.method == 'GET': 
+        token = Token.objects.create(user=User.objects.get(username='api'))    
+        return Response(token)
+    return Response()
+
+@api_view(['GET', 'PUT', 'POST'])
+#@authentication_classes((TokenAuthentication,))
+#@permission_classes((IsAuthenticated,))
+def user_list(request, user_id = 0):
+    if request.method == 'GET':
+        sync_users()
+        if not user_id:
+            users = UserCredit.objects.all()
+            serializer = UserCreditSerializer(users, many=True)
+        else:
+            user = UserCredit.objects.get(uid=user_id)
+            serializer = UserCreditSerializer(user)
+        return Response(serializer.data)        
     elif request.method == 'PUT':
+        if not user_id:
+            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
+            
         sync_users()
         try:
-            UserCredit.objects.get(uid=request.data['uid'])
+            user = UserCredit.objects.get(uid=user_id)
+            if "credit" in request.data:
+                user.credit = request.data['credit']
+            if "card_id" in request.data:
+                user.card_id = request.data['card_id']
+            user.save();
+            return Response(UserCreditSerializer(user).data)
         except UserCredit.DoesNotExist:
-            u = UserCredit(uid=request.data['uid'], credit=0.0)
-            u.save()
+            return Response(status=status.HTTP_404_NOT_FOUND)
         return Response()
+        
+    elif request.method == 'POST':
+        card_id=""
+        if not 'uid' in request.data:
+            return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
+        if 'card_id' in request.data:
+            card_id = request.data['card_id']
+        u = UserCredit(uid=request.data['uid'], card_id=card_id, credit=0.0)
+        try:
+            u.save()
+            state=status.HTTP_201_CREATED
+        except IntegrityError as e:
+            u = UserCredit.objects.get(uid=request.data['uid'])
+            state=status.HTTP_409_CONFLICT
+        
+        serializer = UserCreditSerializer(u)
+        return Response(serializer.data, status=state)
+    return Response()
+    
 
 def sync_users():
     for user in LdapUser.objects.all():
         try:
-            u = UserCredit(uid=user, credit=0.0)
+            u = UserCredit(uid=user.uid, card_id=user.card_id, credit=0.0)
             u.save()
         except IntegrityError:
             pass
+        except:
+            pass
diff --git a/www/web/warpzone.db b/www/web/warpzone.db
index 81069c749d4e6fcb5e38e98ea3925bf3623b89e0..2b253a2ff47ee5cbffbec87ac395208a4e2984fe 100644
GIT binary patch
literal 79872
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

literal 76800
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
A`2YX_

-- 
GitLab