mirror of
https://github.com/spl0k/supysonic.git
synced 2024-12-22 17:06:17 +00:00
Ability to grant jukebox right when creating an user from the API
This commit is contained in:
parent
c2f5ec43b9
commit
debb396b0e
@ -691,7 +691,7 @@ No parameter
|
|||||||
| `adminRole` | | ✔️ |
|
| `adminRole` | | ✔️ |
|
||||||
| `settingsRole` | | |
|
| `settingsRole` | | |
|
||||||
| `streamRole` | | |
|
| `streamRole` | | |
|
||||||
| `jukeboxRole` | | 📅 |
|
| `jukeboxRole` | | ✔️ |
|
||||||
| `downloadRole` | | |
|
| `downloadRole` | | |
|
||||||
| `uploadRole` | | |
|
| `uploadRole` | | |
|
||||||
| `playlistRole` | | |
|
| `playlistRole` | | |
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
# coding: utf-8
|
|
||||||
#
|
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
#
|
#
|
||||||
# Copyright (C) 2013-2018 Alban 'spl0k' Féron
|
# Copyright (C) 2013-2020 Alban 'spl0k' Féron
|
||||||
#
|
#
|
||||||
# Distributed under terms of the GNU AGPLv3 license.
|
# Distributed under terms of the GNU AGPLv3 license.
|
||||||
|
|
||||||
@ -49,17 +47,26 @@ def users_info():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_roles_dict():
|
||||||
|
roles = {}
|
||||||
|
for role in ("admin", "jukebox"):
|
||||||
|
value = request.values.get(role + "Role")
|
||||||
|
value = value in (True, "True", "true", 1, "1")
|
||||||
|
roles[role] = value
|
||||||
|
|
||||||
|
return roles
|
||||||
|
|
||||||
|
|
||||||
@api.route("/createUser.view", methods=["GET", "POST"])
|
@api.route("/createUser.view", methods=["GET", "POST"])
|
||||||
@admin_only
|
@admin_only
|
||||||
def user_add():
|
def user_add():
|
||||||
username = request.values["username"]
|
username = request.values["username"]
|
||||||
password = request.values["password"]
|
password = request.values["password"]
|
||||||
email = request.values["email"]
|
email = request.values["email"]
|
||||||
admin = request.values.get("adminRole")
|
roles = get_roles_dict()
|
||||||
admin = True if admin in (True, "True", "true", 1, "1") else False
|
|
||||||
|
|
||||||
password = decode_password(password)
|
password = decode_password(password)
|
||||||
UserManager.add(username, password, email, admin)
|
UserManager.add(username, password, mail=email, **roles)
|
||||||
|
|
||||||
return request.formatter.empty
|
return request.formatter.empty
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# coding: utf-8
|
|
||||||
#
|
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
#
|
#
|
||||||
@ -375,7 +373,7 @@ class SupysonicCLI(cmd.Cmd):
|
|||||||
try:
|
try:
|
||||||
if not password:
|
if not password:
|
||||||
password = self._ask_password() # pragma: nocover
|
password = self._ask_password() # pragma: nocover
|
||||||
UserManager.add(name, password, email, False)
|
UserManager.add(name, password, mail=email)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.write_error_line(str(e))
|
self.write_error_line(str(e))
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
# coding: utf-8
|
|
||||||
#
|
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
#
|
#
|
||||||
@ -231,8 +229,9 @@ def add_user_form():
|
|||||||
@admin_only
|
@admin_only
|
||||||
def add_user_post():
|
def add_user_post():
|
||||||
error = False
|
error = False
|
||||||
(name, passwd, passwd_confirm, mail, admin) = map(
|
args = request.form.copy()
|
||||||
request.form.get, ["user", "passwd", "passwd_confirm", "mail", "admin"]
|
(name, passwd, passwd_confirm) = map(
|
||||||
|
args.pop, ["user", "passwd", "passwd_confirm"], [None] * 3
|
||||||
)
|
)
|
||||||
if not name:
|
if not name:
|
||||||
flash("The name is required.")
|
flash("The name is required.")
|
||||||
@ -244,13 +243,9 @@ def add_user_post():
|
|||||||
flash("The passwords don't match.")
|
flash("The passwords don't match.")
|
||||||
error = True
|
error = True
|
||||||
|
|
||||||
admin = admin is not None
|
|
||||||
if mail is None:
|
|
||||||
mail = ""
|
|
||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
try:
|
try:
|
||||||
UserManager.add(name, passwd, mail, admin)
|
UserManager.add(name, passwd, **args)
|
||||||
flash("User '%s' successfully added" % name)
|
flash("User '%s' successfully added" % name)
|
||||||
return redirect(url_for("frontend.user_index"))
|
return redirect(url_for("frontend.user_index"))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
# coding: utf-8
|
|
||||||
#
|
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
#
|
#
|
||||||
# Copyright (C) 2013-2018 Alban 'spl0k' Féron
|
# Copyright (C) 2013-2020 Alban 'spl0k' Féron
|
||||||
# 2017 Óscar García Amor
|
# 2017 Óscar García Amor
|
||||||
#
|
#
|
||||||
# Distributed under terms of the GNU AGPLv3 license.
|
# Distributed under terms of the GNU AGPLv3 license.
|
||||||
@ -31,15 +29,12 @@ class UserManager:
|
|||||||
return User[uid]
|
return User[uid]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add(name, password, mail, admin):
|
def add(name, password, **kwargs):
|
||||||
if User.exists(name=name):
|
if User.exists(name=name):
|
||||||
raise ValueError("User '{}' exists".format(name))
|
raise ValueError("User '{}' exists".format(name))
|
||||||
|
|
||||||
crypt, salt = UserManager.__encrypt_password(password)
|
crypt, salt = UserManager.__encrypt_password(password)
|
||||||
|
return User(name=name, password=crypt, salt=salt, **kwargs)
|
||||||
user = User(name=name, mail=mail, password=crypt, salt=salt, admin=admin)
|
|
||||||
|
|
||||||
return user
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete(uid):
|
def delete(uid):
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding: utf-8
|
|
||||||
#
|
#
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
#
|
#
|
||||||
# Copyright (C) 2017-2018 Alban 'spl0k' Féron
|
# Copyright (C) 2017-2020 Alban 'spl0k' Féron
|
||||||
# 2017 Óscar García Amor
|
# 2017 Óscar García Amor
|
||||||
#
|
#
|
||||||
# Distributed under terms of the GNU AGPLv3 license.
|
# Distributed under terms of the GNU AGPLv3 license.
|
||||||
@ -98,19 +97,37 @@ class UserTestCase(ApiTestBase):
|
|||||||
self.assertEqual(child.get("username"), "charlie")
|
self.assertEqual(child.get("username"), "charlie")
|
||||||
self.assertEqual(child.get("email"), "unicorn@example.com")
|
self.assertEqual(child.get("email"), "unicorn@example.com")
|
||||||
self.assertEqual(child.get("adminRole"), "true")
|
self.assertEqual(child.get("adminRole"), "true")
|
||||||
|
self.assertEqual(child.get("jukeboxRole"), "true") # admin gives full control
|
||||||
|
|
||||||
self._make_request(
|
self._make_request(
|
||||||
"createUser",
|
"createUser",
|
||||||
{"username": "dave", "password": "Dav3", "email": "dave@example.com"},
|
{
|
||||||
|
"username": "dave",
|
||||||
|
"password": "Dav3",
|
||||||
|
"email": "dave@example.com",
|
||||||
|
"jukeboxRole": True,
|
||||||
|
},
|
||||||
skip_post=True,
|
skip_post=True,
|
||||||
)
|
)
|
||||||
rv, child = self._make_request("getUser", {"username": "dave"}, tag="user")
|
rv, child = self._make_request("getUser", {"username": "dave"}, tag="user")
|
||||||
self.assertEqual(child.get("username"), "dave")
|
self.assertEqual(child.get("username"), "dave")
|
||||||
self.assertEqual(child.get("email"), "dave@example.com")
|
self.assertEqual(child.get("email"), "dave@example.com")
|
||||||
self.assertEqual(child.get("adminRole"), "false")
|
self.assertEqual(child.get("adminRole"), "false")
|
||||||
|
self.assertEqual(child.get("jukeboxRole"), "true")
|
||||||
|
|
||||||
|
self._make_request(
|
||||||
|
"createUser",
|
||||||
|
{"username": "eve", "password": "3ve", "email": "eve@example.com"},
|
||||||
|
skip_post=True,
|
||||||
|
)
|
||||||
|
rv, child = self._make_request("getUser", {"username": "eve"}, tag="user")
|
||||||
|
self.assertEqual(child.get("username"), "eve")
|
||||||
|
self.assertEqual(child.get("email"), "eve@example.com")
|
||||||
|
self.assertEqual(child.get("adminRole"), "false")
|
||||||
|
self.assertEqual(child.get("jukeboxRole"), "false")
|
||||||
|
|
||||||
rv, child = self._make_request("getUsers", tag="users")
|
rv, child = self._make_request("getUsers", tag="users")
|
||||||
self.assertEqual(len(child), 4)
|
self.assertEqual(len(child), 5)
|
||||||
|
|
||||||
def test_delete_user(self):
|
def test_delete_user(self):
|
||||||
# non admin
|
# non admin
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding: utf-8
|
|
||||||
#
|
#
|
||||||
# This file is part of Supysonic.
|
# This file is part of Supysonic.
|
||||||
# Supysonic is a Python implementation of the Subsonic server API.
|
# Supysonic is a Python implementation of the Subsonic server API.
|
||||||
@ -31,15 +30,15 @@ class UserManagerTestCase(unittest.TestCase):
|
|||||||
@db_session
|
@db_session
|
||||||
def create_data(self):
|
def create_data(self):
|
||||||
# Create some users
|
# Create some users
|
||||||
self.assertIsInstance(
|
alice = UserManager.add("alice", "ALICE", admin=True)
|
||||||
UserManager.add("alice", "ALICE", "test@example.com", True), db.User
|
self.assertIsInstance(alice, db.User)
|
||||||
)
|
self.assertTrue(alice.admin)
|
||||||
self.assertIsInstance(
|
|
||||||
UserManager.add("bob", "BOB", "bob@example.com", False), db.User
|
bob = UserManager.add("bob", "BOB")
|
||||||
)
|
self.assertIsInstance(bob, db.User)
|
||||||
self.assertIsInstance(
|
self.assertFalse(bob.admin)
|
||||||
UserManager.add("charlie", "CHARLIE", "charlie@example.com", False), db.User
|
|
||||||
)
|
self.assertIsInstance(UserManager.add("charlie", "CHARLIE"), db.User)
|
||||||
|
|
||||||
folder = db.Folder(name="Root", path="tests/assets", root=True)
|
folder = db.Folder(name="Root", path="tests/assets", root=True)
|
||||||
artist = db.Artist(name="Artist")
|
artist = db.Artist(name="Artist")
|
||||||
@ -97,9 +96,7 @@ class UserManagerTestCase(unittest.TestCase):
|
|||||||
self.assertEqual(db.User.select().count(), 3)
|
self.assertEqual(db.User.select().count(), 3)
|
||||||
|
|
||||||
# Create duplicate
|
# Create duplicate
|
||||||
self.assertRaises(
|
self.assertRaises(ValueError, UserManager.add, "alice", "Alic3", admin=True)
|
||||||
ValueError, UserManager.add, "alice", "Alic3", "alice@example.com", True
|
|
||||||
)
|
|
||||||
|
|
||||||
@db_session
|
@db_session
|
||||||
def test_delete_user(self):
|
def test_delete_user(self):
|
||||||
|
@ -93,8 +93,8 @@ class TestBase(unittest.TestCase):
|
|||||||
self.client = self.__app.test_client()
|
self.client = self.__app.test_client()
|
||||||
|
|
||||||
with db_session:
|
with db_session:
|
||||||
UserManager.add("alice", "Alic3", "test@example.com", True)
|
UserManager.add("alice", "Alic3", admin=True)
|
||||||
UserManager.add("bob", "B0b", "bob@example.com", False)
|
UserManager.add("bob", "B0b")
|
||||||
|
|
||||||
def _patch_client(self):
|
def _patch_client(self):
|
||||||
self.client.get = patch_method(self.client.get)
|
self.client.get = patch_method(self.client.get)
|
||||||
|
Loading…
Reference in New Issue
Block a user