Improvements to the hosting management app server side logic.

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1517420 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
jsdelfino 2013-08-26 05:18:10 +00:00
commit 9837026758
21 changed files with 490 additions and 188 deletions

View file

@ -21,22 +21,70 @@ from atomutil import *
from sys import debug
# Convert a particular user id to an account id
def accountid(user):
return ('accounts', user.get(()), 'user.account')
def accountid(uid):
return ('accounts', uid, 'user.account')
# Get the current user's account
# Get a user account
def get(id, user, cache):
debug('accounts.py::get::id', id)
account = cache.get(accountid(user))
# Default to the current user's account
uid = user.get(()) if isNull(id) else car(id)
# Get the account
account = cache.get(accountid(uid))
if isNull(account):
return mkentry(user.get(()), user.get(()), user.get(()), now(), ())
return mkentry(uid, uid, uid, now(), ())
# Strip private info from account
if uid != user.get(()) and user.get(()) != 'admin':
desc = assoc("'description", content(account))
return mkentry(title(account), uid, uid, now(), ("'account",) + (() if isNull(desc) else (desc,)))
return account
# Update the user's account
# Update a user account
def put(id, account, user, cache):
debug('accounts.py::put::id', id)
debug('accounts.py::put::account', account)
accountentry = mkentry(title(account), user.get(()), user.get(()), now(), content(account))
return cache.put(accountid(user), accountentry)
# Default to the current user's account
uid = user.get(()) if isNull(id) else car(id)
# Only the admin can create or update somebody else's account
if uid != user.get(()) and user.get(()) != 'admin':
debug('accounts.py::put', 'not owner or admin', user.get(()))
return False
# Get existing account
eaccount = cache.get(accountid(uid))
if isNull(eaccount) and user.get(()) != 'admin':
# Only the admin can create a new account
debug('accounts.py::put', 'account not found', (uid,))
return False
# Merge new account info
email = assoc("'email", content(account)) if isNull(eaccount) else assoc("'email", content(eaccount))
desc = assoc("'description", content(account))
accountentry = mkentry(title(account), uid, uid, now(), ("'account",) + (() if isNull(email) else (email,)) + (() if isNull(desc) else (desc,)))
return cache.put(accountid(uid), accountentry)
def delete(id, user, cache):
debug('accounts.py::delete::id', id)
uid = car(id)
# Only the admin can delete an account
if user.get(()) != 'admin':
debug('accounts.py::delete', 'not admin', user.get(()))
return False
# Get the requested id
account = cache.get(accountid(uid))
if isNull(account):
debug('accounts.py::delete', 'account not found', (uid,))
return False
# Delete the account
return cache.delete(accountid(uid))

View file

@ -83,12 +83,12 @@ def get(id, user, cache, db, dashboard, store, composites, pages, icons):
# Return the newest apps
if isNull(id):
newentries = db.get((("'regex", '("apps" .* "app.info")'), ("'rank", "(regexp_matches(value, '(.*\(updated )([^\)]+)(\).*)'))[2]::timestamp"), ("'limit", 25)))
flatentries = tuple(map(lambda v: car(v), () if isNull(newentries) else newentries))
def sortkey(e):
return updated((e,))
sortedentries = tuple(sorted(flatentries, key = sortkey, reverse = True))[0:25]
newapps = ((("'feed", ("'title", "Apps"), ("'id", 'apps')) + sortedentries),)
newentries = db.get((("'regex", '("apps" .* "app.info")'), ("'rank", "(regexp_matches(value, '(.*\\(updated )([^\\)]+)(\\).*)'))[2]::timestamp"), ("'limit", 50)))
entries = tuple(map(lambda v: car(v), () if isNull(newentries) else newentries))
#def sortkey(e):
# return updated((e,))
#sortedentries = tuple(sorted(entries, key = sortkey, reverse = True))
newapps = ((("'feed", ("'title", "Apps"), ("'id", 'apps')) + entries),)
debug('apps.py::get::newapps', newapps)
return newapps

View file

@ -97,8 +97,11 @@ def get(id, user, cache, apps, ratings):
return findapp(id, cdr(dashboard))
if isNull(id):
dashboardapps = mergeapps(getdashboard(dashboardid(user), cache), apps, ratings)
dashboard = ((("'feed", ("'title", "Your Apps"), ("'id", user.get(()))) + dashboardapps),)
entries = mergeapps(getdashboard(dashboardid(user), cache), apps, ratings)
def sortkey(e):
return updated((e,))
sortedentries = tuple(sorted(entries, key = sortkey, reverse = True))
dashboard = ((("'feed", ("'title", "Your Apps"), ("'id", user.get(()))) + sortedentries),)
debug('dashboards.py::get::dashboard', dashboard)
return dashboard

View file

@ -0,0 +1,57 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
host=$5
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
else
scheme="https"
port="443"
fi
# Delete user account
curl -k -L -u $admin:$apass -X DELETE -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Accounts/$user

View file

@ -18,43 +18,42 @@
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
email=$4
host=$5
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
port="443"
fi
# Compute user id
slash=`echo $user | grep "/"`
if [ "$slash" = "" ]; then
id="\"$user\""
upath=$user
else
id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
fi
# Compute user URI
upath=$email
# Delete user auth
curl -k -L -u $admin:$apass -X DELETE -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Authenticator/$upath

View file

@ -0,0 +1,57 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
host=$5
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
else
scheme="https"
port="443"
fi
# Get user account
curl -k -L -u $admin:$apass -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Accounts/$user

View file

@ -18,44 +18,42 @@
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
email=$4
host=$5
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
port="443"
fi
# Compute user id
slash=`echo $user | grep "/"`
if [ "$slash" = "" ]; then
id="\"$user\""
upath=$user
else
id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
fi
# Compute user URI
upath=$email
# Get user auth
curl -k -L -u $admin:$apass -H "X-Forwarded-Server: $host" $scheme://$host:$port/c/Authenticator/$upath

View file

@ -16,32 +16,15 @@
# under the License.
# App icons collection implementation
from StringIO import StringIO
try:
from PIL import Image
except:
Image = None
from base64 import b64encode, b64decode
from urllib import urlopen
from util import *
from atomutil import *
from imgutil import *
from sys import debug
# Convert an id to an icon id
def iconid(id):
return ("apps", car(id), "app.icon")
# Convert image to a 50x50 PNG image
def to50x50png(url):
debug('icons.py::to50x50png::url', url)
if Image is None:
return url
img = Image.open(StringIO(b64decode(url.split(',')[1])) if url.startswith('data:') else StringIO(urlopen(url).read()))
t = img.resize((50, 50))
obuf = StringIO()
t.save(obuf, 'PNG')
return 'data:image/png;base64,' + b64encode(obuf.getvalue()).replace('\n', '')
# Put an icon
def put(id, icon, user, cache, apps):
debug('icons.py::put::id', id)
@ -61,7 +44,7 @@ def put(id, icon, user, cache, apps):
# Get image and token from input icon
def image(c):
img = assoc("'image", c)
return None if isNull(img) else to50x50png(cadr(img))
return None if isNull(img) else urlto50x50jpeg(cadr(img))
def token(c):
tok = assoc("'token", c)
return None if isNull(tok) else cadr(tok)

View file

@ -20,12 +20,11 @@ from imaplib2 import IMAP4_SSL
from threading import Thread, Event
from email import message_from_string
import re
from StringIO import StringIO
from PIL import Image
from base64 import b64encode, b64decode
from httplib import HTTPConnection, HTTPSConnection
from urlparse import urlparse
from util import *
from imgutil import *
from sys import stderr, argv, exit
from traceback import print_exc
@ -64,12 +63,8 @@ def fetchmail(id, imap):
if len(parts) == 0:
return (None, 'Email doesn\'t contain an image')
# Convert image to a 50x50 PNG image
img = Image.open(StringIO(parts[0]))
t = img.resize((50, 50))
obuf = StringIO()
t.save(obuf, 'PNG')
dataurl = 'data:image/png;base64,' + b64encode(obuf.getvalue()).replace('\n', '')
# Convert image to a 50x50 JPEG image
dataurl = bufto50x50jpeg(parts[0])
# Return address, image url pair
return (address, dataurl)

View file

@ -0,0 +1,106 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# Image processing functions
from StringIO import StringIO
try:
from PIL import Image
from PIL import ImageOps
from PIL import ExifTags
except:
Image = None
from base64 import b64encode, b64decode
from urllib import urlopen
from util import *
from sys import debug
# Rotate image if needed
def rotateimg(img):
debug('imgutil.py::rotateimg')
if not hasattr(img, '_getexif'):
return img
exif = img._getexif()
if exif is None:
return img
for tag, value in exif.items():
decoded = ExifTags.TAGS.get(tag, tag)
if decoded == 'Orientation':
if value == 3: return img.rotate(180)
if value == 6: return img.rotate(270)
if value == 8: return img.rotate(90)
return img
# Convert image to a cropped thumbnail
def thumbnail(img, size):
def intsz(*nums):
return tuple(int(round(n)) for n in nums)
class imgsz(object):
def __init__(self, pair):
self.width = float(pair[0])
self.height = float(pair[1])
self.aspect_ratio = self.width / self.height
self.size = intsz(self.width, self.height)
osz = imgsz(img.size)
tsz = imgsz(size)
if tsz.aspect_ratio > osz.aspect_ratio:
scale = tsz.width / osz.width
crop = imgsz((osz.width, tsz.height / scale))
cut = (osz.height - crop.height) / 2
img = img.crop(intsz(0, cut, crop.width, cut + crop.height))
elif tsz.aspect_ratio < osz.aspect_ratio:
scale = tsz.height / osz.height
crop = imgsz((tsz.width / scale, osz.height))
cut = (osz.width - crop.width) / 2
img = img.crop(intsz(cut, 0, cut + crop.width, crop.height))
return img.resize(tsz.size, Image.ANTIALIAS)
# Convert image URL to a 50x50 JPEG
def urlto50x50jpeg(url):
debug('imgutil.py::urlto50x50jpeg::url', url)
if Image is None:
return url
img = Image.open(StringIO(b64decode(url.split(',')[1])) if url.startswith('data:') else StringIO(urlopen(url).read()))
if img.size == (50, 50):
debug('imgutil.py::urlto50x50jpeg::res', url)
return url
thumb = thumbnail(rotateimg(img), (50, 50))
obuf = StringIO()
thumb.save(obuf, 'JPEG')
res = 'data:image/jpeg;base64,' + b64encode(obuf.getvalue()).replace('\n', '')
debug('imgutil.py::urlto50x50jpeg::res', res)
return res;
# Convert image to a 50x50 JPEG
def bufto50x50jpeg(buf):
debug('imgutil.py::bufto50x50jpeg')
if Image is None:
return ''
img = Image.open(StringIO(buf))
if img.size == (50, 50):
debug('imgutil.py::urlto50x50jpeg::res', url)
return url
thumb = thumbnail(rotateimg(img), (50, 50))
obuf = StringIO()
thumb.save(obuf, 'JPEG')
res = 'data:image/jpeg;base64,' + b64encode(obuf.getvalue()).replace('\n', '')
debug('imgutil.py::bufto50x50jpeg::res', res)
return res

View file

@ -19,17 +19,19 @@
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
cd $here
var=$HOME/var
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
user=$1
pass=$2
email=$1
user=$2
pass=$3
tmp=$3
tmp=$4
if [ "$tmp" = "" ]; then
tmp="$here/tmp"
fi
host=$4
mkdir -p $tmp/sqldb
host=$5
if [ "$host" = "" ]; then
host="localhost"
fi
@ -37,21 +39,16 @@ fi
# Get password hash
rm -f $tmp/sqldb/load-authn.passwd
touch $tmp/sqldb/load-authn.passwd
$httpd_prefix/bin/htpasswd -b $tmp/sqldb/load-authn.passwd "$user" "$pass" 2>/dev/null
$httpd_prefix/bin/htpasswd -b $tmp/sqldb/load-authn.passwd "$email" "$pass" 2>/dev/null
hash=`cat $tmp/sqldb/load-authn.passwd | awk -F ":" '{ print $2 }'`
rm -f $tmp/sqldb/load-authn.passwd
# Compute user id
slash=`echo $user | grep "/"`
if [ "$slash" = "" ]; then
id="\"$user\""
else
id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
fi
id="\"$email\""
# Load into database
cat >$tmp/sqldb/load-authn.sql <<EOF
insert into data values('("authn" $id "user.authn")', '((entry (title "$user") (id "$user") (content (hash "$hash"))))');
insert into data values('("authn" $id "user.authn")', '((entry (title "$email") (id "$email") (content (user "$user") (hash "$hash"))))');
EOF
$here/../../components/sqldb/pgsql <$tmp/sqldb/load-authn.sql

View file

@ -16,32 +16,16 @@
# under the License.
# Pictures collection implementation
from StringIO import StringIO
try:
from PIL import Image
except:
Image = None
from base64 import b64encode, b64decode
from urllib import urlopen
from util import *
from atomutil import *
from imgutil import *
from sys import debug
# Convert a particular user id to a picture id
def pictureid(id):
return ('accounts', id, 'user.picture')
# Convert image to a 50x50 PNG image
def to50x50png(url):
debug('pictures.py::to50x50png::url', url)
if Image is None:
return url
img = Image.open(StringIO(b64decode(url.split(',')[1])) if url.startswith('data:') else StringIO(urlopen(url).read()))
t = img.resize((50, 50))
obuf = StringIO()
t.save(obuf, 'PNG')
return 'data:image/png;base64,' + b64encode(obuf.getvalue()).replace('\n', '')
# Update the user's picture
def put(id, picture, user, cache):
debug('pictures.py::put::id', id)
@ -57,7 +41,7 @@ def put(id, picture, user, cache):
# Get image and token from input picture
def image(c):
img = assoc("'image", c)
return None if isNull(img) else to50x50png(cadr(img))
return None if isNull(img) else urlto50x50jpeg(cadr(img))
def token(c):
tok = assoc("'token", c)
return None if isNull(tok) else cadr(tok)

View file

@ -0,0 +1,72 @@
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
email=$5
host=$6
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
else
scheme="https"
port="443"
fi
# Put user account
cat >$root/conf/account.entry <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title type="text"></title>
<id>$user</id>
<content type="application/xml">
<account>
<email>$email</email>
<description></description>
</account>
</content>
</entry>
EOF
curl -k -L -u $admin:$apass -X PUT -H "X-Forwarded-Server: $host" --data-binary @$root/conf/account.entry $scheme://$host:$port/c/Accounts/$user
rm $root/conf/account.entry

View file

@ -18,60 +18,63 @@
# under the License.
here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
mkdir -p $1
mkdir -p $1/conf
root=`echo "import os; print os.path.realpath('$1')" | python`
admin=$2
apass=$3
user=$4
upass=$5
email=$4
user=$5
upass=$6
host=$7
httpd_prefix=`cat $here/../../modules/http/httpd.prefix`
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
if [ "$host" = "" ]; then
conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"`
sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"`
if [ "$sslconf" = "" ]; then
scheme="http"
addr=`echo $conf | awk '{ print $7 }'`
host=`$here/../../modules/http/httpd-addr ip $addr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
fi
port=`$here/../../modules/http/httpd-addr port $addr`
else
scheme="https"
ssladdr=`echo $sslconf | awk '{ print $6 }'`
host=`$here/../../modules/http/httpd-addr ip $ssladdr`
if [ "$host" = "" ]; then
host="localhost"
fi
port=`$here/../../modules/http/httpd-addr port $ssladdr`
port="443"
fi
# Get password hash
rm -f $root/conf/auth.passwd
touch $root/conf/auth.passwd
$httpd_prefix/bin/htpasswd -b $root/conf/auth.passwd "$user" "$upass" 2>/dev/null
$httpd_prefix/bin/htpasswd -b $root/conf/auth.passwd "$email" "$upass" 2>/dev/null
hash=`cat $root/conf/auth.passwd | awk -F ":" '{ print $2 }'`
rm -f $root/conf/auth.passwd
# Compute user id
slash=`echo $user | grep "/"`
if [ "$slash" = "" ]; then
id="\"$user\""
upath=$user
else
id=`echo $user | awk -F "/" '{ printf "\"%s\" \"%s\"", $2, $3 }'`
upath=`echo $user | awk -F "/" '{ printf "%s/%s", $2, $3 }'`
fi
# Compute user URI
upath=$email
# Put user auth
cat >$root/conf/auth.entry <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
<title type="text">$user</title>
<id>$user</id>
<title type="text">$email</title>
<id>$email</id>
<content type="application/xml">
<hash>$hash</hash>
<authn>
<user>$user</user>
<hash>$hash</hash>
</authn>
</content>
</entry>
EOF

View file

@ -108,12 +108,12 @@ def get(id, user, cache, db, apps):
# Return the top ratings
if isNull(id):
topentries = db.get((("'regex", '("ratings" .* "app.ratings")'), ("'rank", "(regexp_matches(value, '(.*\(rating )([^\)]+)(\).*)'))[2]::float"), ("'limit", 25)))
flatentries = tuple(map(lambda v: car(v), () if isNull(topentries) else topentries))
def sortkey(e):
return cadr(assoc("'rating", assoc("'ratings", assoc("'content", e))))
sortedentries = tuple(sorted(flatentries, key = sortkey, reverse = True))[0:25]
topratings = ((("'feed", ("'title", "Ratings"), ("'id", 'ratings')) + sortedentries),)
topentries = db.get((("'regex", '("ratings" .* "app.ratings")'), ("'rank", "(regexp_matches(value, '(.*\\(rating )([^\\)]+)(\\).*)'))[2]::float"), ("'limit", 50)))
entries = tuple(map(lambda v: car(v), () if isNull(topentries) else topentries))
#def sortkey(e):
# return cadr(assoc("'rating", assoc("'ratings", assoc("'content", e))))
#sortedentries = tuple(sorted(entries, key = sortkey, reverse = True))
topratings = ((("'feed", ("'title", "Ratings"), ("'id", 'ratings')) + entries),)
debug('ratings.py::get::topratings', topratings)
return topratings

View file

@ -45,7 +45,7 @@ def get(id, user, cache, db, apps, ratings):
return None
# Run the search
foundentries = db.get((("'regex", '("apps" .* "app.info")'), ("'textsearch", cadr(q)), ("'limit", 25)))
foundentries = db.get((("'regex", '("apps" .* "app.info")'), ("'textsearch", cadr(q)), ("'limit", 50)))
debug('search.py::get::foundentries', foundentries)
# Merge app ratings

View file

@ -173,12 +173,9 @@ EOF
sleep 2
# Configure authorized users
./put-auth tmp admin admin admin admin
./put-auth tmp admin admin john john
./put-auth tmp admin admin jane jane
# Configure the email addresses associated with your OAuth ids here
./put-auth tmp admin admin /oauth1/john@example.com password
./put-auth tmp admin admin /oauth2/jane@example.com password
./put-auth tmp admin admin admin@example.com admin admin
./put-auth tmp admin admin john@example.com john john
./put-auth tmp admin admin jane@example.com jane jane
# Clear document cache
rm -rf tmp/proxy/cache

View file

@ -209,10 +209,7 @@ EOF
sleep 2
# Configure authorized users
./put-auth tmp admin admin admin admin
./put-auth tmp admin admin john john
./put-auth tmp admin admin jane jane
# Configure the email addresses associated with your OAuth ids here
./put-auth tmp admin admin /oauth1/john@example.com password
./put-auth tmp admin admin /oauth2/jane@example.com password
./put-auth tmp admin admin admin@example.com admin admin
./put-auth tmp admin admin john@example.com john john
./put-auth tmp admin admin jane@example.com jane jane

View file

@ -51,7 +51,7 @@ import search
def testUser():
# Return current user
assert user.get((), mkprop('user', lambda: 'johndoe'), mkprop('email', lambda: 'jdoe@example.com'), mkprop('nick', lambda: 'jdoe'), mkprop('full', lambda: 'john doe'), mkprop('first', lambda: 'john'), mkprop('last', lambda: 'doe'), mkprop('realm', lambda: 'example.com'), mkprop('host', lambda: 'localhost')) == 'jdoe@example.com'
assert user.get((), mkprop('user', lambda: 'jdoe'), mkprop('email', lambda: 'jdoe@example.com'), mkprop('nick', lambda: 'jdoe'), mkprop('full', lambda: 'john doe'), mkprop('first', lambda: 'john'), mkprop('last', lambda: 'doe'), mkprop('realm', lambda: 'example.com'), mkprop('host', lambda: 'localhost')) == 'jdoe'
return True
def testAccounts():
@ -60,20 +60,24 @@ def testAccounts():
assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {})) == defaccount
# Get user's account
jdoe = (("'entry", ("'title", 'John Doe'), ("'id", 'jdoe@example.com'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'key", 'value'))),)
jdoe = (("'entry", ("'title", 'John Doe'), ("'id", 'jdoe@example.com'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'account", ("'email", 'jdoe@example.com'), ("'description", 'This is joe')))),)
assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), mkcache('cache', {('accounts', 'jdoe@example.com', 'user.account') : jdoe})) == jdoe
# Put and get account
cache1 = mkcache('cache', {})
assert accounts.put((), jdoe, mkref('user', lambda id: 'jdoe@example.com'), cache1) == True
cache1 = mkcache('cache', {('accounts', 'jdoe@example.com', 'user.account') : jdoe})
jdoe1 = (("'entry", ("'title", 'John Doe'), ("'id", 'jdoe@example.com'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'account", ("'email", 'bad@example.com'), ("'description", 'This is joe')))),)
jdoe2 = (("'entry", ("'title", 'John Doe'), ("'id", 'jdoe@example.com'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'account", ("'email", 'jdoe@example.com'), ("'description", 'This is joe again')))),)
assert accounts.put((), jdoe1, mkref('user', lambda id: 'jdoe@example.com'), cache1) == True
assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1) == jdoe
assert accounts.put((), jdoe2, mkref('user', lambda id: 'jdoe@example.com'), cache1) == True
assert accounts.get((), mkref('user', lambda id: 'jdoe@example.com'), cache1) == jdoe2
return True
def testPictures():
if PIL is None:
return True
img16 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAOUlEQVQ4y2N0b3/7nwEH2FkpzGg7hQGn/OEcBkYmBgrBqAFUMIBiQDCeL3qY4ZTX33FqNB0Mj3QAAFC7Dhs7i7zzAAAAAElFTkSuQmCC'
img50 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAg0lEQVR4nO3YsRVFUBAG4Xu1oBCZTEwxGlDBa0AxxDKZQtRARAfrzWG+aLP/TLq5/e1HCjAPZb7uZkwhG0uf7o0iYuAfDKExhMYQGkNoDKExhMYQGkNoDKExRPqI/MTzbOvqkI1qWn3QYRlCYwiNITSG0BhCYwiNITSG0BhC85oQKcgJzukOV+8REuQAAAAASUVORK5CYII='
img16 = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAOUlEQVQ4y2N0b3/7nwEH2FkpzGg7hQGn/OEcBkYmBgrBqAFUMIBiQDCeL3qY4ZTX33FqNB0Mj3QAAFC7Dhs7i7zzAAAAAElFTkSuQmCC'
img50 = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAACV0lEQVR4nO2YPU8UURSG3zMzO2wiIrguXwmthSEkJtBZmFgYG6n5Rf4VKmlILIw/YIstNgoVJhICy8zuyrIzy97vY6F8aH2LG3Of8hbnzZOZM5P70tsPI4ZHjKyr8ujwoN/7uD86+fK5tYXd9jb2WlvYpQSZjwwrUA17OBh0sX91jE8AkPgYHAJRJDSiSGhEkdCIIqERRUIjioRGFAmNKBIaUSQ0MiPryudAK+vaGSHYWQMA7GCcxsxKVESe7uwStdMQ7GBuz7Ly6PDAx/C7ECPF5LzXVXVZgMFqjPPqBzpsoUFIfWSwhqjP0NUTFLdn9Oz5m3c+ht+FOGtUXRayKvrqZjTMH2MlX8BaYwHL8PUqOxg1QaEm6OsaAwAgXxXNPzAzHBhMABFRQgB5DQCYmR0DDABZawu7XgMcjBzjQo1xpico2s18fbWZb7TnGutE5EXGOjalVBeXQp2NpL4EgKy9jT0fw29xCrPqFJ3r7zCmosFqM994uTj/anNxfieBnx0Rzs2+jacd6ypzJ+L7iViBylnoWYkTAVC7ma9vPnm083p58X1K5OU1nhpbWcf69Eac4M83N/O9I5QgowQp6PdOEEAJUZoSZb5EUqIsIUof7t1/80OMIqERRUIjioRGFAmNKBIaUSQ0okhoRJHQyKyA54Lu7/LMMhvp3GxqbOXrhnhjbS2dE5b5vqAb9uC1oHtYnjHApVDnX8fTjmHWCchL+SCdE8fX0+5I6fuCbukFvBZ0D8szU2P4dK6x0p5rrLXyhreCzjLMT6WLgVT9K2UGPmZGfPMLWsI5A943r6EAAAAASUVORK5CYII='
# Put and get picture
pic16 = (("'entry", ("'title", 'jdoe@example.com'), ("'id", 'jdoe@example.com'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'picture", ("'image", img16)))),)
@ -120,8 +124,8 @@ def testPages():
def testIcons():
if PIL is None:
return True
img16 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAOUlEQVQ4y2N0b3/7nwEH2FkpzGg7hQGn/OEcBkYmBgrBqAFUMIBiQDCeL3qY4ZTX33FqNB0Mj3QAAFC7Dhs7i7zzAAAAAElFTkSuQmCC'
img50 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAg0lEQVR4nO3YsRVFUBAG4Xu1oBCZTEwxGlDBa0AxxDKZQtRARAfrzWG+aLP/TLq5/e1HCjAPZb7uZkwhG0uf7o0iYuAfDKExhMYQGkNoDKExhMYQGkNoDKExRPqI/MTzbOvqkI1qWn3QYRlCYwiNITSG0BhCYwiNITSG0BhC85oQKcgJzukOV+8REuQAAAAASUVORK5CYII='
img16 = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAOUlEQVQ4y2N0b3/7nwEH2FkpzGg7hQGn/OEcBkYmBgrBqAFUMIBiQDCeL3qY4ZTX33FqNB0Mj3QAAFC7Dhs7i7zzAAAAAElFTkSuQmCC'
img50 = 'data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAACV0lEQVR4nO2YPU8UURSG3zMzO2wiIrguXwmthSEkJtBZmFgYG6n5Rf4VKmlILIw/YIstNgoVJhICy8zuyrIzy97vY6F8aH2LG3Of8hbnzZOZM5P70tsPI4ZHjKyr8ujwoN/7uD86+fK5tYXd9jb2WlvYpQSZjwwrUA17OBh0sX91jE8AkPgYHAJRJDSiSGhEkdCIIqERRUIjioRGFAmNKBIaUSQ0MiPryudAK+vaGSHYWQMA7GCcxsxKVESe7uwStdMQ7GBuz7Ly6PDAx/C7ECPF5LzXVXVZgMFqjPPqBzpsoUFIfWSwhqjP0NUTFLdn9Oz5m3c+ht+FOGtUXRayKvrqZjTMH2MlX8BaYwHL8PUqOxg1QaEm6OsaAwAgXxXNPzAzHBhMABFRQgB5DQCYmR0DDABZawu7XgMcjBzjQo1xpico2s18fbWZb7TnGutE5EXGOjalVBeXQp2NpL4EgKy9jT0fw29xCrPqFJ3r7zCmosFqM994uTj/anNxfieBnx0Rzs2+jacd6ypzJ+L7iViBylnoWYkTAVC7ma9vPnm083p58X1K5OU1nhpbWcf69Eac4M83N/O9I5QgowQp6PdOEEAJUZoSZb5EUqIsIUof7t1/80OMIqERRUIjioRGFAmNKBIaUSQ0okhoRJHQyKyA54Lu7/LMMhvp3GxqbOXrhnhjbS2dE5b5vqAb9uC1oHtYnjHApVDnX8fTjmHWCchL+SCdE8fX0+5I6fuCbukFvBZ0D8szU2P4dK6x0p5rrLXyhreCzjLMT6WLgVT9K2UGPmZGfPMLWsI5A943r6EAAAAASUVORK5CYII='
# Get default icon
deficon = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content",)),)
@ -137,6 +141,7 @@ def testIcons():
# Put and get a icon
cache1 = mkcache('cache', {})
icon1updated = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'icon", ("'image", img50)))),)
assert icons.put(('app1',), icon1, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id, app = None: app1 if app is None else True)) == True
assert icons.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == icon1updated
@ -153,8 +158,10 @@ def testIcons():
# Put an upload token in an icon
icon1token = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'icon", ("'token", '1234')))),)
assert icons.put(('app1',), icon1token, mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == True
assert icons.get(('app1',), mkref('user', lambda id: 'another@example.com'), cache1, mkref('apps', lambda id: app1)) == icon1updated
icon1updatedwithtoken = (("'entry", ("'title", 'app1'), ("'id", 'app1'), ("'author", 'jdoe@example.com'), ("'updated", '2012-01-01T00:00:00+00:00'), ("'content", ("'icon", ("'image", img50), ("'token", '1234')))),)
assert icons.get(('app1',), mkref('user', lambda id: 'jdoe@example.com'), cache1, mkref('apps', lambda id: app1)) == icon1updatedwithtoken

View file

@ -19,8 +19,6 @@
# Return the current user id
def get(i, user, email, nick, full, first, last, realm, host):
if email.eval() != '?':
return email.eval()
if user.eval() != '?':
return user.eval()
return 'anonymous'

View file

@ -132,7 +132,8 @@ def cons_stream(car, cdr):
def assoc(k, l):
if l == ():
return ()
if k == car(car(l)):
a = car(l)
if isTaggedList(a, k):
return car(l)
return assoc(k, cdr(l))