senec 0.22.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec_status +70 -70
- data/.ruby-lsp/Gemfile.lock +67 -56
- data/.ruby-lsp/last_updated +1 -1
- data/.ruby-lsp/main_lockfile_hash +1 -1
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +56 -27
- data/coverage/coverage.json +55 -26
- data/coverage/index.html +706 -390
- data/lib/senec/cloud/connection.rb +37 -10
- data/lib/senec/version.rb +1 -1
- data/pkg/senec-0.22.1.gem +0 -0
- metadata +3 -3
- data/.ruby-lsp/needs_update +0 -0
|
@@ -40,8 +40,8 @@ module Senec
|
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
# Manual HTTP needed for Keycloak cross-domain form handling
|
|
43
|
-
|
|
44
|
-
redirect_url = submit_credentials(
|
|
43
|
+
form_type, form_url = fetch_login_form(auth_url)
|
|
44
|
+
redirect_url = submit_credentials(form_type, form_url)
|
|
45
45
|
authorization_code = extract_authorization_code(redirect_url)
|
|
46
46
|
|
|
47
47
|
self.oauth_token =
|
|
@@ -80,15 +80,19 @@ module Senec
|
|
|
80
80
|
|
|
81
81
|
attr_accessor :oauth_token
|
|
82
82
|
|
|
83
|
-
def
|
|
83
|
+
def fetch_login_form(auth_url)
|
|
84
84
|
response = http_request(:get, auth_url)
|
|
85
85
|
store_cookies(response) # Required for Keycloak CSRF protection
|
|
86
|
-
|
|
86
|
+
detect_login_form(response.body) || raise('Login form not found')
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
-
def submit_credentials(form_url)
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
def submit_credentials(form_type, form_url)
|
|
90
|
+
case form_type
|
|
91
|
+
when :username_and_password
|
|
92
|
+
response = http_request(:post, form_url, data: { username:, password: })
|
|
93
|
+
when :username_only
|
|
94
|
+
response = submit_username_then_password(form_url)
|
|
95
|
+
end
|
|
92
96
|
|
|
93
97
|
if response.status == 200
|
|
94
98
|
# Check if MFA is required
|
|
@@ -108,6 +112,20 @@ module Senec
|
|
|
108
112
|
handle_redirect_response(response)
|
|
109
113
|
end
|
|
110
114
|
|
|
115
|
+
def submit_username_then_password(form_url)
|
|
116
|
+
response = http_request(:post, form_url, data: { username: })
|
|
117
|
+
store_cookies(response)
|
|
118
|
+
|
|
119
|
+
raise 'Password form not found' unless response.status == 200
|
|
120
|
+
|
|
121
|
+
password_form_url = find_form_action_url(response.body) do |f|
|
|
122
|
+
f.match(/name=["']?password["']?/i)
|
|
123
|
+
end
|
|
124
|
+
raise 'Password form not found' unless password_form_url
|
|
125
|
+
|
|
126
|
+
http_request(:post, password_form_url, data: { username:, password: })
|
|
127
|
+
end
|
|
128
|
+
|
|
111
129
|
def submit_totp_form(form_url)
|
|
112
130
|
totp = build_totp_from_uri(totp_uri)
|
|
113
131
|
|
|
@@ -124,12 +142,21 @@ module Senec
|
|
|
124
142
|
params['code'] || raise('No authorization code found')
|
|
125
143
|
end
|
|
126
144
|
|
|
127
|
-
def
|
|
128
|
-
|
|
129
|
-
|
|
145
|
+
def detect_login_form(html)
|
|
146
|
+
# Check for combined form first (backward compatible with old SENEC flow)
|
|
147
|
+
url = find_form_action_url(html) do |form|
|
|
130
148
|
form.match(/name=["']?username["']?/i) &&
|
|
131
149
|
form.match(/name=["']?password["']?/i)
|
|
132
150
|
end
|
|
151
|
+
return [:username_and_password, url] if url
|
|
152
|
+
|
|
153
|
+
# Check for username-only form (new two-step SENEC flow)
|
|
154
|
+
url = find_form_action_url(html) do |form|
|
|
155
|
+
form.match(/name=["']?username["']?/i)
|
|
156
|
+
end
|
|
157
|
+
return [:username_only, url] if url
|
|
158
|
+
|
|
159
|
+
nil
|
|
133
160
|
end
|
|
134
161
|
|
|
135
162
|
def extract_totp_form_action_url(html)
|
data/lib/senec/version.rb
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: senec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.23.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Georg Ledermann
|
|
@@ -98,7 +98,6 @@ files:
|
|
|
98
98
|
- ".ruby-lsp/Gemfile.lock"
|
|
99
99
|
- ".ruby-lsp/last_updated"
|
|
100
100
|
- ".ruby-lsp/main_lockfile_hash"
|
|
101
|
-
- ".ruby-lsp/needs_update"
|
|
102
101
|
- ".vscode/settings.json"
|
|
103
102
|
- CODE_OF_CONDUCT.md
|
|
104
103
|
- LICENSE
|
|
@@ -166,6 +165,7 @@ files:
|
|
|
166
165
|
- pkg/senec-0.20.0.gem
|
|
167
166
|
- pkg/senec-0.21.0.gem
|
|
168
167
|
- pkg/senec-0.22.0.gem
|
|
168
|
+
- pkg/senec-0.22.1.gem
|
|
169
169
|
- pkg/senec-0.3.0.gem
|
|
170
170
|
- pkg/senec-0.4.0.gem
|
|
171
171
|
- pkg/senec-0.5.0.gem
|
|
@@ -199,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
199
199
|
- !ruby/object:Gem::Version
|
|
200
200
|
version: '0'
|
|
201
201
|
requirements: []
|
|
202
|
-
rubygems_version:
|
|
202
|
+
rubygems_version: 4.0.7
|
|
203
203
|
specification_version: 4
|
|
204
204
|
summary: Unofficial Ruby Client for SENEC Home
|
|
205
205
|
test_files: []
|
data/.ruby-lsp/needs_update
DELETED
|
File without changes
|