octoprint_auth_ldap.plugin   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 100
dl 0
loc 139
rs 10
c 0
b 0
f 0
wmc 18

9 Methods

Rating   Name   Duplication   Size   Complexity  
B AuthLDAPPlugin.migrate_settings_1_to_2() 0 24 5
A AuthLDAPPlugin.get_settings_restricted_paths() 0 5 1
A AuthLDAPPlugin.ldap_user_factory() 0 3 1
A AuthLDAPPlugin.check_config() 0 14 1
A AuthLDAPPlugin.get_settings_defaults() 0 25 1
A AuthLDAPPlugin.get_settings_version() 0 2 1
A AuthLDAPPlugin.on_settings_migrate() 0 8 4
A AuthLDAPPlugin.migrate_settings_2_to_3() 0 22 3
A AuthLDAPPlugin.get_template_configs() 0 3 1
1
# coding=utf-8
2
from __future__ import absolute_import
3
4
from octoprint.plugin import TemplatePlugin, RestartNeedingPlugin
5
from octoprint.settings import settings
6
from octoprint_auth_ldap.constants import DEFAULT_ADMIN_GROUP, DEFAULT_USER_GROUP, OU_FILTER, OU_MEMBER_FILTER, OU, \
7
    REQUEST_TLS_CERT, SEARCH_BASE, URI
8
from octoprint_auth_ldap.ldap import LDAPConnection
9
from octoprint_auth_ldap.tweaks import SettingsPlugin
10
from octoprint_auth_ldap.user_manager import LDAPUserManager
11
12
13
class AuthLDAPPlugin(SettingsPlugin, TemplatePlugin, RestartNeedingPlugin):
14
    # noinspection PyUnusedLocal,PyShadowingNames
15
    def ldap_user_factory(self, components, settings):
16
        self._user_manager = LDAPUserManager(plugin=self, ldap=LDAPConnection(plugin=self))
17
        return self._user_manager
18
19
    # Softwareupdate hook
20
21
    def check_config(self):
22
        return dict(
23
            auth_ldap=dict(
24
                displayName=self._plugin_name,
25
                displayVersion=self._plugin_version,
26
27
                # version check: github repository
28
                type="github_release",
29
                user="battis",
30
                repo="OctoPrint-LDAP",
31
                current=self._plugin_version,
32
33
                # update method: pip
34
                pip="https://github.com/battis/OctoPrint-LDAP/archive/{target_version}.zip"
35
            )
36
        )
37
38
    # SettingsPlugin
39
40
    def get_settings_defaults(self):
41
        return dict(
42
            auth_password=None,
43
            auth_user=None,
44
            default_admin_group=False,
45
            default_user_group=True,
46
47
            # TODO expose in settings GUi
48
            ldap_group_key_prefix="ldap_",
49
            ldap_parent_group_description="Generated by %s plugin, with membership synced automatically based on LDAP "
50
                                          "configuration" % self._plugin_name,
51
            ldap_parent_group_key="ldap",
52
            ldap_parent_group_name="LDAP-Authenticated Users",
53
54
            ou_filter="ou=%s",
55
            ou_member_filter="uniqueMember=%s",
56
            ou=None,
57
            local_cache=False,
58
            request_tls_cert=None,
59
            search_base=None,
60
            search_filter="uid=%s",
61
            search_term_transform=None,
62
            uri=None,
63
            userid_field=None,
64
            userid_pattern=None
65
        )
66
67
    def get_settings_restricted_paths(self):
68
        return dict(
69
            admin=self.get_settings_defaults().keys(),
70
            user=[],
71
            never=[]
72
        )
73
74
    def get_settings_version(self):
75
        return 3
76
77
    def on_settings_migrate(self, target, current):
78
        if target != current:
79
            self._logger.info(
80
                "Migrating %s settings from version %s to version %s" % (self._plugin_name, current, target))
81
            if current is None:
82
                self.migrate_settings_1_to_2()
83
            if current != 3:  # intentional fall-through to bring None _and_ 2 to 3 (my kingdom for a switch statement!)
84
                self.migrate_settings_2_to_3()
85
86
    def migrate_settings_1_to_2(self):
87
        # changing settings location to plugin standard location and renaming to simplify access
88
        self._logger.debug("Attempting to migrate settings from version 1 to version 2")
89
90
        # migrate old settings to new locations and erase old settings
91
        prev_settings = dict(  # prev_setting_name="new_setting_name"
92
            ldap_uri=URI,
93
            ldap_tls_reqcert=REQUEST_TLS_CERT,
94
            ldap_search_base=SEARCH_BASE,
95
            ldap_groups="groups"
96
        )
97
        for prev_key, key in prev_settings.items():
98
            prev_value = settings().get(["accessControl", prev_key])
99
            if prev_value is not None:
100
                cleaned_prev_value = prev_value
101
                if prev_key == "ldap_tls_reqcert" and prev_value == "demand":
102
                    cleaned_prev_value = True
103
                self.settings.set([key], cleaned_prev_value)
104
                self._logger.info(
105
                    "accessControl.%s=%s setting migrated to plugins.%s.%s=%s"
106
                    % (prev_key, prev_value, self._identifier, key, cleaned_prev_value))
107
            else:
108
                self._logger.debug('accessControl.%s=None, migration not necessary' % prev_key)
109
            settings().set(["accessControl", prev_key], None)
110
111
    def migrate_settings_2_to_3(self):
112
        # renaming to get rid of roles in favor of local groups, and clarifying LDAP group settings
113
        self._logger.debug("Attempting to migrate settings from version 2 to version 3")
114
115
        # migrate old settings to new locations and erase old settings
116
        prev_settings = dict(  # prev_setting_name="new_setting_name"
117
            default_role_admin=DEFAULT_ADMIN_GROUP,
118
            default_role_user=DEFAULT_USER_GROUP,
119
            group_filter=OU_FILTER,
120
            group_member_filter=OU_MEMBER_FILTER,
121
            groups=OU
122
        )
123
        for prev_key, key in prev_settings.items():
124
            prev_value = self.settings.get([prev_key])
125
            if prev_value is not None:
126
                self.settings.set([key], prev_value)
127
                self._logger.info(
128
                    "plugin.%s.%s=%s setting migrated to plugins.%s.%s=%s"
129
                    % (self._identifier, prev_key, prev_value, self._identifier, key, prev_value))
130
            else:
131
                self._logger.debug('plugin.%s.%s=None, migration not necessary' % (self._identifier, prev_key))
132
            self.settings.set([prev_key], None)
133
134
    # TemplatePlugin
135
136
    def get_template_configs(self):
137
        return [
138
            dict(type="settings", custom_bindings=False),  # must mark custom_bindings False to load settings in GUI
139
        ]
140