[Bf-extensions-cvs] [84a9344] master: Fix T49008: Blender-ID add-on for inclusion as OFFICIAL

Sybren A. Stüvel noreply at git.blender.org
Sun Aug 7 11:37:58 CEST 2016


Commit: 84a93440fd5c5ecbe80d7bb9743c1747d0bde3eb
Author: Sybren A. Stüvel
Date:   Sun Aug 7 11:37:23 2016 +0200
Branches: master
https://developer.blender.org/rBA84a93440fd5c5ecbe80d7bb9743c1747d0bde3eb

Fix T49008: Blender-ID add-on for inclusion as OFFICIAL

Added Blender-ID add-on version 1.2.0.

For more info, see the repository at
https://developer.blender.org/diffusion/BIA/

To bundle a new version, run this from the Blender-ID add-on source:

python3 setup.py bdist bundle --path /path/to/blender/release/scripts/addons

===================================================================

A	blender_id/README.md
A	blender_id/__init__.py
A	blender_id/communication.py
A	blender_id/profiles.py

===================================================================

diff --git a/blender_id/README.md b/blender_id/README.md
new file mode 100644
index 0000000..936e6e3
--- /dev/null
+++ b/blender_id/README.md
@@ -0,0 +1,109 @@
+Blender ID addon
+================
+
+This addon allows you to authenticate your Blender with your
+[Blender ID](https://www.blender.org/id/) account. This authentication
+can then be used by other addons, such as the
+[Blender Cloud addon](https://developer.blender.org/diffusion/BCA/)
+
+Blender compatibility
+---------------------
+
+Blender ID add-on version 1.2.0 removed some workarounds necessary for
+Blender 2.77a. As such, versions 1.1.x are the last versions compatible with
+Blender 2.77a, and 1.2.0 and newer require at least Blender 2.78.
+
+Building & Bundling
+-------------------
+
+* To build the addon, run `python3 setup.py bdist`
+* To bundle the addon with Blender, run `python3 setup.py bdist bundle --path
+  ../blender-git/blender/release/scripts/addons`.
+* If you don't want to bundle, you can install the addon from Blender
+  (User Preferences → Addons → Install from file...) by pointing it to
+  `dist/blender_id*.addon.zip`.
+
+
+Using the addon
+---------------
+
+* Install the addon as described above.
+* Enable the addon in User Preferences → Addons → System.
+* Sign up for an account at the
+  [Blender ID site](https://www.blender.org/id/) if you don't have an
+  account yet.
+* Log in with your Blender ID and password. You only have to do this
+  once.
+
+Your password is never saved on your machine, just an access token. It
+is stored next to your Blender configuration files, in
+
+* Linux and similar: `$HOME/.config/blender/{version}/config/blender_id`
+* MacOS: `$HOME/Library/Application Support/Blender/{version}/config/blender_id`
+* Windows: `%APPDATA%\Blender Foundation\Blender\{version}\config\blender_id`
+
+where `{version}` is the Blender version.
+
+
+Using the addon from another addon
+----------------------------------
+
+The following functions can be used from other addons to use the Blender
+ID functionality:
+
+**blender_id.get_active_profile()** returns the `BlenderIdProfile` that
+represents the currently logged in user, or `None` when the user isn't
+logged in:
+
+    lang=python
+    class BlenderIdProfile:
+        user_id = '41234'
+        username = 'username at example.com'
+        token = '41344124-auth-token-434134'
+
+
+**blender_id.get_active_user_id()** returns the user ID of the logged
+in user, or `''` when the user isn't logged in.
+
+**blender_id.is_logged_in()** returns `True` if the user is logged
+in, and `False` otherwise.
+
+
+Here is an example of a simple addon that shows your username in its
+preferences panel:
+
+    lang=python,name=demo_blender_id_addon.py
+    # Extend this with your info
+    bl_info = {
+        'name': 'Demo addon using Blender ID',
+        'location': 'Add-on preferences',
+        'category': 'System',
+        'support': 'TESTING',
+    }
+
+    import bpy
+
+
+    class DemoPreferences(bpy.types.AddonPreferences):
+        bl_idname = __name__
+
+        def draw(self, context):
+            import blender_id
+
+            profile = blender_id.get_active_profile()
+            if profile:
+                self.layout.label('You are logged in as %s' % profile.username)
+            else:
+                self.layout.label('You are not logged in on Blender ID')
+
+
+    def register():
+        bpy.utils.register_module(__name__)
+
+
+    def unregister():
+        bpy.utils.unregister_module(__name__)
+
+
+    if __name__ == '__main__':
+        register()
diff --git a/blender_id/__init__.py b/blender_id/__init__.py
new file mode 100644
index 0000000..ae24af8
--- /dev/null
+++ b/blender_id/__init__.py
@@ -0,0 +1,277 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+bl_info = {
+    'name': 'Blender ID authentication',
+    'author': 'Francesco Siddi, Inês Almeida and Sybren A. Stüvel',
+    'version': (1, 2, 0),
+    'blender': (2, 77, 0),
+    'location': 'Add-on preferences',
+    'description':
+        'Stores your Blender ID credentials for usage with other add-ons',
+    'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/'
+                'Scripts/System/BlenderID',
+    'category': 'System',
+    'support': 'OFFICIAL',
+}
+
+import bpy
+from bpy.types import AddonPreferences, Operator, PropertyGroup
+from bpy.props import PointerProperty, StringProperty
+
+if 'communication' in locals():
+    import importlib
+
+    # noinspection PyUnboundLocalVariable
+    communication = importlib.reload(communication)
+    # noinspection PyUnboundLocalVariable
+    profiles = importlib.reload(profiles)
+else:
+    from . import communication, profiles
+BlenderIdProfile = profiles.BlenderIdProfile
+BlenderIdCommError = communication.BlenderIdCommError
+
+__all__ = ('get_active_profile', 'get_active_user_id', 'is_logged_in', 'create_subclient_token',
+           'BlenderIdProfile', 'BlenderIdCommError')
+
+
+# Public API functions
+def get_active_user_id() -> str:
+    """Get the id of the currently active profile. If there is no
+    active profile on the file, this function will return an empty string.
+    """
+
+    return BlenderIdProfile.user_id
+
+
+def get_active_profile() -> BlenderIdProfile:
+    """Returns the active Blender ID profile. If there is no
+    active profile on the file, this function will return None.
+
+    :rtype: BlenderIdProfile
+    """
+
+    if not BlenderIdProfile.user_id:
+        return None
+
+    return BlenderIdProfile
+
+
+def is_logged_in() -> bool:
+    """Returns whether the user is logged in on Blender ID or not."""
+
+    return bool(BlenderIdProfile.user_id)
+
+
+def create_subclient_token(subclient_id: str, webservice_endpoint: str) -> dict:
+    """Lets the Blender ID server create a subclient token.
+
+    :param subclient_id: the ID of the subclient
+    :param webservice_endpoint: the URL of the endpoint of the webservice
+        that belongs to this subclient.
+    :returns: the token along with its expiry timestamp, in a {'scst': 'token',
+        'expiry': datetime.datetime} dict.
+    :raises: blender_id.communication.BlenderIdCommError when the
+        token cannot be created.
+    """
+
+    # Communication between us and Blender ID.
+    profile = get_active_profile()
+    scst_info = communication.subclient_create_token(profile.token, subclient_id)
+    subclient_token = scst_info['token']
+
+    # Send the token to the webservice.
+    user_id = communication.send_token_to_subclient(webservice_endpoint, profile.user_id,
+                                                    subclient_token, subclient_id)
+
+    # Now that everything is okay we can store the token locally.
+    profile.subclients[subclient_id] = {'subclient_user_id': user_id, 'token': subclient_token}
+    profile.save_json()
+
+    return scst_info
+
+
+def get_subclient_user_id(subclient_id: str) -> str:
+    """Returns the user ID at the given subclient.
+
+    Requires that the user has been authenticated at the subclient using
+    a call to create_subclient_token(...)
+
+    :returns: the subclient-local user ID, or None if not logged in.
+    """
+
+    if not BlenderIdProfile.user_id:
+        return None
+
+    return BlenderIdProfile.subclients[subclient_id]['subclient_user_id']
+
+
+class BlenderIdPreferences(AddonPreferences):
+    bl_idname = __name__
+
+    error_message = StringProperty(
+        name='Error Message',
+        default='',
+        options={'HIDDEN', 'SKIP_SAVE'}
+    )
+    ok_message = StringProperty(
+        name='Message',
+        default='',
+        options={'HIDDEN', 'SKIP_SAVE'}
+    )
+    blender_id_username = StringProperty(
+        name='E-mail address',
+        default='',
+        options={'HIDDEN', 'SKIP_SAVE'}
+    )
+    blender_id_password = StringProperty(
+        name='Password',
+        default='',
+        options={'HIDDEN', 'SKIP_SAVE'},
+        subtype='PASSWORD'
+    )
+
+    def reset_messages(self):
+        self.ok_message = ''
+        self.error_message = ''
+
+    def draw(self, context):
+        layout = self.layout
+
+        if self.error_message:
+            sub = layout.row()
+            sub.alert = True  # labels don't display in red :(
+            sub.label(self.error_message, icon='ERROR')
+        if self.ok_message:
+            sub = layout.row()
+            sub.label(self.ok_message, icon='FILE_TICK')
+
+        active_profile = get_active_profile()
+        if active_profile:
+            text = 'You are logged in as {0}'.format(active_profile.username)
+            layout.label(text=text, icon='WORLD_DATA')
+            row = layout.row()
+            row.operator('blender_id.logout')
+            if bpy.app.debug:
+                row.operator('blender_id.validate')
+        else:
+            layout.prop(self, 'blender_id_username')
+            layout.prop(self, 'blender_id_password')
+
+            layout.operator('blender_id.login')
+
+
+class BlenderIdMixin:
+    @staticmethod
+    def addon_prefs(context):
+        preferences = context.user_preferences.addons[__name__].preferences
+        preferences.reset_messages()
+        return preferences
+
+
+class BlenderIdLogin(BlenderIdMixin, Operator):
+    bl_idname = 'blender_id.login'
+    bl_label = 'Login'
+
+    def execute(self, context):
+        import random
+        import string
+
+        addon_prefs = self.addon_prefs(context)
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list