Skip to content

Commit

Permalink
rest authenticator works now
Browse files Browse the repository at this point in the history
  • Loading branch information
or-else committed Dec 12, 2018
1 parent 249c28b commit ec64e03
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 46 deletions.
22 changes: 12 additions & 10 deletions rest-auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Sample Tinode REST/JSON-RPC authentication service.
# See https://github.com/tinode/chat/rest-auth for details.

from flask import Flask, jsonify, make_response
from flask import Flask, jsonify, make_response, request
import base64
import json

Expand All @@ -28,25 +28,27 @@ def add():
def auth():
if not request.json:
return jsonify({'err': 'malformed'})
uname, password = parse_secret(request.json.secret)
if dummy_data[uname]:
uname, password = parse_secret(request.json.get('secret'))
if uname in dummy_data:
if dummy_data[uname]['password'] != password:
# Wrong password
return jsonify({'err': 'failed'})
if dummy_data[uname]['uid']:
if 'uid' in dummy_data[uname]:
# We have uname -> uid mapping
jsonify({
return jsonify({
'rec': {
'uid': dummy_data[uname]['uid'],
'authlvl': dummy_data[uname]['authlvl'],
'features': dummy_data[uname]['features']
}
})
else:
# This is the first login. Tell Tinode to create a new account.
jsonify({
return jsonify({
'rec': {
'authlvl': dummy_data[uname]['authlvl'],
'tags': dummy_data[uname]['tags']
'tags': dummy_data[uname]['tags'],
'features': dummy_data[uname]['features']
},
'newacc': {
'auth': dummy_data[uname]['auth'],
Expand Down Expand Up @@ -83,17 +85,17 @@ def link():

# Save the link account <-> secret to database.
uname, password = parse_secret(secret)
if not dummy_data[uname]:
if uname not in dummy_data:
# Unknown user name
return jsonify({'err': 'not found'})
if dummy_data[uname]['uid']:
if 'uid' in dummy_data[uname]:
# Already linked
return jsonify({'err': 'duplicate value'})

# Save updated data to file
dummy_data[uname]['uid'] = rec['uid']
with open('dummy_data.json', 'w') as outfile:
json.dump(dummy_data, outfile)
json.dump(dummy_data, outfile, indent=2, sort_keys=True)

# Success
return jsonify({})
Expand Down
93 changes: 58 additions & 35 deletions rest-auth/dummy_data.json
Original file line number Diff line number Diff line change
@@ -1,107 +1,130 @@
{
"alice": {
"password": "alice123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:alice@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "alice123",
"private": "email:bob@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com",
"public": {
"fn": "Alice Johnson",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAQUGAwQI/8QAKRAAAgEDAgQFBQAAAAAAAAAAAQIDAAQRBTEGIUFREhMUYYEiQnGCo//EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/EAB4RAAICAgMBAQAAAAAAAAAAAAECABEDIRNB4YGR/9oADAMBAAIRAxEAPwD1TQ5YoZ5ikvFNzJBpywWsvl3d3ItvEw3Utuw91UM361CaFzSKXYKO475GjSLhS9kvdKX1bq95bs1vO22XQ4Jx0zgN+CKd53oDYuHQoxU9QNvjoaj9Tj1DU+MFGny28cOlw/U00RkBmk7AMMFUH9asCcVhDDFG80kcaI0z+Nyox4jgLk9zgAfAoy3qbxZeMlgN1X75cl9GF7pXFdxbahJbyDU4/URtDEY18yMBXGCx5lSh3+01Y965praKWeCWREaSFiY2ZQSpIwSD05Ej5rUNge+9FFakzZeQhq3W/nlT/9k=",
"type": "jpeg"
}
},
"private": "email:bob@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com"
"tags": [
"email:alice@example.com"
],
"uid": "QVuwC5jz9o4"
},
"bob": {
"password": "bob123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:bob@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "bob123",
"private": "email:alice@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com",
"public": {
"fn": "Bob Smith",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGgABAAEFAAAAAAAAAAAAAAAABQMAAQIECP/EACkQAAEDAgQFBAMAAAAAAAAAAAECAwQAEQUSITETIjJBgUJRUnFhofD/xAAXAQEBAQEAAAAAAAAAAAAAAAAAAgED/8QAHxEAAQUBAAIDAAAAAAAAAAAAEQABAgMSMXGhE2Hw/9oADAMBAAIRAxEAPwDqisb+4FWvv4obFC65i8RlD7rLamXVnIQLkKQBuPyaicsMQudk8RIPPacBvtVeKEw5x5M5yOp9choNhZUoDMg32JAA286U3SE9MUrntiFHbTXqIoTForMrHYKJLaFpDDx5hf1N07/CtSbAizVIMuOy8UdPEQFW+r1lsNsPCm2v5IZB536dFxG2oWLJjYblDRbUp1pJ5UG4ym3Ym6vvxT99NRUEWMxFa4cdpDSPigAD9VOe9zSuGGH5kprww9NxvC//2Q==",
"type": "jpeg"
}
},
"private": "email:alice@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com"
"tags": [
"email:bob@example.com"
],
"uid": "Pp-n0RjGm8s"
},
"carol": {
"password": "carol123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:carol@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "carol123",
"private": "email:alice@example.com,email:bob@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com",
"public": {
"fn": "Carol Xmas",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAQUGBAMI/8QAJRAAAQQCAQMEAwAAAAAAAAAAAQIDBAUAERITIVEGMUFxFCJh/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQL/xAAdEQEAAgEFAQAAAAAAAAAAAAABABECAxIhMcFB/9oADAMBAAIRAxEAPwD1RrAO31hyPkuzL71JPr4816DXVnBEhUfiHXnlpC+HIg8UhBSTrSiVDuAP2cNPdfNBywWpYYcU1Ncuv6iVWE2WlWilMlSVdP6ISD3/AKT7feNsEBobjB8ZH0zyK71vfwJJ6blk43YRSo9nQGW2VpT5KS0CR4cTlhmC0qoFqwGbKHGlsg8g2+0HEg+dH5ysMjGx6SvfIJNgcSVFOxyA2RnTFlVS1tQlxNVXxIYcIK/x2Q3y17b0O+M8lr51Gf/Z",
"type": "jpeg"
}
},
"private": "email:alice@example.com,email:bob@example.com,email:dave@example.com,email:eve@example.com,email:frank@example.com"
"tags": [
"email:carol@example.com"
]
},
"dave": {
"password": "dave123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:dave@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "dave123",
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:eve@example.com,email:frank@example.com",
"public": {
"fn": "Dave Goliathsson",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAwADAAAAAAAAAAAAAAAAAAQFAgMI/8QAIxAAAgIBAwQDAQAAAAAAAAAAAQIAAxEEITEFEhNBYXOxof/EABcBAQEBAQAAAAAAAAAAAAAAAAECAAP/xAAcEQACAwADAQAAAAAAAAAAAAABAgADERIxwUH/2gAMAwEAAhEDEQA/AOqMQ9wkxksu6lfX57URKkICEcktn18CcbH45g3YgSpCT6bbKtSlF9nkDglHIwduQcbShKRwwhCIVbdX1X01frx6LXaPTXv33UVWPjGXQE4kWKzYV+Hwj2Ii5ZdT1GrxN3JSGLMOMnYD9/kozBFWtQqAADgATZGusrpPZmM//9k=",
"type": "jpeg"
}
},
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:eve@example.com,email:frank@example.com"
"tags": [
"email:dave@example.com"
]
},
"eve": {
"password": "eve123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:eve@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "eve123",
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:dave@example.com,email:frank@example.com",
"public": {
"fn": "Eve Adams",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAQUGAgQI/8QAIxAAAQQCAAcBAQAAAAAAAAAAAgEDBAUAEQYSEyExYXFBkf/EABUBAQEAAAAAAAAAAAAAAAAAAAIB/8QAGxEAAwEBAQEBAAAAAAAAAAAAAQIRABIhA3H/2gAMAwEAAhEDEQA/APVKZlfiZrymSt6EiVxJAhtzpMZgor7pIwSIpEJtIm9ov4RYkXozJE6Ms1R81h/MV1dYcIjIp8yTzJrT5oqD80iY0yEAHzRgAfDcFyUv4EWfxhVtzY7MhsYMgkF0EJEXqM9++VZeMXWVRXWhtLZQIkvp7QFfZFzl351tO3hP5iRuTcvk/DXGtqYFdzrXw2I5Hrm6QIO9eN6zvL1rF1dS1taZnXwIcUyTREwyLaqnvSYyX3kJptuLmm2/u//Z",
"type": "jpeg"
}
},
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:dave@example.com,email:frank@example.com"
"tags": [
"email:eve@example.com"
]
},
"frank": {
"password": "frank123",
"authlvl": "auth",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:frank@example.com"],
"auth": "JRWPA",
"authlvl": "auth",
"features": "V",
"password": "frank123",
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com",
"public": {
"fn": "Frank Singer",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAUCAwQI/8QAJxAAAQQBAgUEAwAAAAAAAAAAAQACAwQREjEFEyFBgQYUU2FxcpH/xAAXAQADAQAAAAAAAAAAAAAAAAAAAQID/8QAHBEBAAMBAQADAAAAAAAAAAAAAQACEQMSUaHh/9oADAMBAAIRAxEAPwDqfHQoIwcdkZ3SXibZZeMVK0diaKJ0ErzyyBkh0YHb7KYazPpfxXc39joeFJYaVR9bUXWZ5tXyuBx+MBbUMdVTUyBCQ8TrR2vUNBkzGvb7aY4P7RJ605VLomGZspa3WGlodjqAdxnwP4nVx2T15nSvl+T6ZCpSgqauRG1mrfHdat0I8qV2XWpUwJ//2Q==",
"type": "jpeg"
}
},
"private": "email:alice@example.com,email:bob@example.com,email:carol@example.com,email:dave@example.com,email:eve@example.com"
"tags": [
"email:frank@example.com"
]
},
"xena": {
"password": "xena123",
"authlvl": "root",
"auth": "JRWPA",
"anon": "N",
"tags": ["email:xena@example.com"],
"auth": "JRWPA",
"authlvl": "root",
"features": "V",
"password": "xena123",
"private": "",
"public": {
"fn": "Xena Peaceful Peasant",
"photo": {
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAAgACADASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAABgAEBQj/xAArEAABAwMCBAQHAAAAAAAAAAABAgMEAAUREjEGISJhNEFRcRQjJTJCQ4L/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A9U1VUeukuRar/EffcUu1TMRVg7R3s/LX7LzoPfR6mgQ1Ue4fmSbvOl3FLhTavDxG88ncHre9ieSeyc/lyQ0FRTi36y43ww2fGtlyaobtRQcHHopZ6R/RH20rrM1GYakOvtstIfeADiwkBS8bZPnjJoOBwbIcYadsM7R8baghoEJwHmP1OgbcwMEDZST5YpRWZUZgy0yiy2ZSUFsO6RqCSQSnO+MgHHatNB//2Q==",
"type": "jpeg"
}
},
"private": ""
"tags": [
"email:xena@example.com"
]
}
}
68 changes: 68 additions & 0 deletions server/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package auth

import (
"errors"
"strconv"
"time"

"github.com/tinode/chat/server/store/types"
Expand Down Expand Up @@ -109,6 +110,73 @@ const (
FeatureNoLogin
)

// MarshalText converts AccessMode to ASCII byte slice.
func (f Feature) MarshalText() ([]byte, error) {
var res = []byte{}
for i, chr := range []byte{'V', 'L'} {
if (f & (1 << uint(i))) != 0 {
res = append(res, chr)
}
}
return res, nil
}

// UnmarshalText parses access mode string as byte slice.
// Does not change the mode if the string is empty or invalid.
func (f *Feature) UnmarshalText(b []byte) error {
var f0 int
var err error
if len(b) > 0 {
if b[0] >= '0' && b[0] <= '9' {
f0, err = strconv.Atoi(string(b))
} else {
for i := 0; i < len(b); i++ {
switch b[i] {
case 'V', 'v':
f0 |= int(FeatureValidated)
case 'L', 'l':
f0 |= int(FeatureNoLogin)
default:
err = errors.New("Feature: invalid character '" + string(b[i]) + "'")
break
}
}
}
}

*f = Feature(f0)

return err
}

// String returns string representation of Feature.
func (f Feature) String() string {
res, err := f.MarshalText()
if err != nil {
return ""
}
return string(res)
}

// MarshalJSON converts AccessMode to a quoted string.
func (f Feature) MarshalJSON() ([]byte, error) {
res, err := f.MarshalText()
if err != nil {
return nil, err
}

return append(append([]byte{'"'}, res...), '"'), nil
}

// UnmarshalJSON reads AccessMode from a quoted string.
func (f *Feature) UnmarshalJSON(b []byte) error {
if b[0] != '"' || b[len(b)-1] != '"' {
return errors.New("syntax error")
}

return f.UnmarshalText(b[1 : len(b)-1])
}

// Rec is an authentication record.
type Rec struct {
// User ID
Expand Down
6 changes: 5 additions & 1 deletion server/auth/rest/auth_rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (a *authenticator) Init(jsonconf string) error {
// Server may create new accounts.
AllowNewAccounts bool `json:"allow_new_accounts"`
// Use separate endpoints, i.e. add request name to serverUrl path when making requests.
UseSeparateEndpoints bool `json:"use_separae_endpoints"`
UseSeparateEndpoints bool `json:"use_separate_endpoints"`
}

var config configType
Expand Down Expand Up @@ -216,3 +216,7 @@ func (a *authenticator) DelRecords(uid types.Uid) error {
_, err := a.callEndpoint("del", &auth.Rec{Uid: uid}, nil)
return err
}

func init() {
store.RegisterAuthScheme("rest", &authenticator{})
}
1 change: 1 addition & 0 deletions server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/tinode/chat/server/auth"
_ "github.com/tinode/chat/server/auth/anon"
_ "github.com/tinode/chat/server/auth/basic"
_ "github.com/tinode/chat/server/auth/rest"
_ "github.com/tinode/chat/server/auth/token"

// Database backends
Expand Down

0 comments on commit ec64e03

Please sign in to comment.