Use client headers for OAuth

This commit is contained in:
JonnyWong16 2018-07-02 09:55:28 -07:00
parent 434cb89ba8
commit 3fd0708d21
5 changed files with 89 additions and 86 deletions

File diff suppressed because one or more lines are too long

View file

@ -93,7 +93,85 @@
</div> </div>
<script src="${http_root}js/jquery-2.1.4.min.js"></script> <script src="${http_root}js/jquery-2.1.4.min.js"></script>
<script src="${http_root}js/platform.min.js"></script>
<script> <script>
function uuidv4() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
const x_plex_headers = {
'Accept': 'application/json',
'X-Plex-Product': '${plexpy.common.PRODUCT}',
'X-Plex-Version': '${plexpy.common.RELEASE}',
'X-Plex-Client-Identifier': uuidv4(),
'X-Plex-Platform': platform.name,
'X-Plex-Platform-Version': platform.version,
'X-Plex-Device': platform.os.toString(),
'X-Plex-Device-Name': platform.name
};
getPlexOAuthPin = function () {
var deferred = $.Deferred();
$.ajax({
url: 'https://plex.tv/api/v2/pins?strong=true',
type: 'POST',
headers: x_plex_headers,
success: function(data) {
deferred.resolve({pin: data.id, code: data.code});
},
error: function() {
deferred.reject();
}
});
return deferred;
};
var polling = null;
$('#sign-in-plex').click(function() {
clearTimeout(polling);
getPlexOAuthPin().then(function (data) {
const pin = data.pin;
const code = data.code;
var keep_polling = true;
window.open('https://app.plex.tv/auth/#!?clientID=' + x_plex_headers['X-Plex-Client-Identifier'] + '&code=' + code);
(function poll() {
polling = setTimeout(function () {
$.ajax({
url: 'https://plex.tv/api/v2/pins/' + pin,
type: 'GET',
headers: x_plex_headers,
success: function (data) {
if (data.authToken){
keep_polling = false;
signIn(true, data.authToken);
}
},
error: function () {
keep_polling = false;
$('#sign-in-plex-alert').text('Error communicating with Plex.tv.').show();
},
complete: function () {
if (keep_polling){
poll();
} else {
clearTimeout(polling);
}
},
timeout: 1000
});
}, 1000);
})();
}, function () {
$('#sign-in-plex-alert').text('Error communicating with Plex.tv.').show();
});
});
$('#login-form').submit(function(event) { $('#login-form').submit(function(event) {
event.preventDefault(); event.preventDefault();
signIn(false); signIn(false);
@ -144,89 +222,6 @@
} }
}); });
} }
getPlexOAuthURL = function () {
var deferred = $.Deferred();
$.ajax({
url: 'https://plex.tv/api/v2/pins?strong=true',
type: 'POST',
headers: {
'Accept': 'application/json',
'X-Plex-Product': 'Tautulli',
'X-Plex-Version': '${plexpy.common.RELEASE}',
'X-Plex-Client-Identifier': '${plexpy.CONFIG.PMS_UUID}',
'X-Plex-Platform': '${plexpy.common.PLATFORM}',
'X-Plex-Platform-Version': '${plexpy.common.PLATFORM_RELEASE}',
'X-Plex-Device': 'Web',
'X-Plex-Device-Name': '${plexpy.common.PLATFORM_DEVICE_NAME}'
},
success: function(data) {
const pin = data.id;
const code = data.code;
const url = 'https://app.plex.tv/auth/#!?clientID=' + '${plexpy.CONFIG.PMS_UUID}' + '&code=' + code;
data = {pin: pin, url: url };
deferred.resolve(data);
},
error: function() {
deferred.reject();
}
});
return deferred;
};
var polling = null;
$('#sign-in-plex').click(function() {
clearTimeout(polling);
getPlexOAuthURL().then(function (data) {
const url = data.url;
const pin = data.pin;
var keep_polling = true;
window.open(url);
(function poll() {
polling = setTimeout(function () {
$.ajax({
url: 'https://plex.tv/api/v2/pins/' + pin,
type: 'GET',
headers: {
'Accept': 'application/json',
'X-Plex-Product': 'Tautulli',
'X-Plex-Version': '${plexpy.common.RELEASE}',
'X-Plex-Client-Identifier': '${plexpy.CONFIG.PMS_UUID}',
'X-Plex-Platform': '${plexpy.common.PLATFORM}',
'X-Plex-Platform-Version': '${plexpy.common.PLATFORM_RELEASE}',
'X-Plex-Device': 'Web',
'X-Plex-Device-Name': '${plexpy.common.PLATFORM_DEVICE_NAME}'
},
success: function (data) {
if (data.authToken){
keep_polling = false;
signIn(true, data.authToken);
}
},
error: function () {
keep_polling = false;
$('#sign-in-plex-alert').text('Error communicating with Plex.tv.').show();
},
complete: function () {
if (keep_polling){
poll();
} else {
clearTimeout(polling);
}
},
timeout: 1000
});
}, 1000);
})();
}, function () {
$('#sign-in-plex-alert').text('Error communicating with Plex.tv.').show();
});
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -1863,7 +1863,7 @@ def generate_uuid():
def initialize_tracker(): def initialize_tracker():
data = { data = {
'dataSource': 'server', 'dataSource': 'server',
'appName': 'Tautulli', 'appName': common.PRODUCT,
'appVersion': common.RELEASE, 'appVersion': common.RELEASE,
'appId': plexpy.INSTALL_TYPE, 'appId': plexpy.INSTALL_TYPE,
'appInstallerId': plexpy.CONFIG.GIT_BRANCH, 'appInstallerId': plexpy.CONFIG.GIT_BRANCH,

View file

@ -19,6 +19,7 @@ from collections import OrderedDict
import version import version
# Identify Our Application # Identify Our Application
PRODUCT = 'Tautulli'
PLATFORM = platform.system() PLATFORM = platform.system()
PLATFORM_RELEASE = platform.release() PLATFORM_RELEASE = platform.release()
PLATFORM_VERSION = platform.version() PLATFORM_VERSION = platform.version()
@ -27,7 +28,7 @@ PLATFORM_DEVICE_NAME = platform.node()
BRANCH = version.PLEXPY_BRANCH BRANCH = version.PLEXPY_BRANCH
RELEASE = version.PLEXPY_RELEASE_VERSION RELEASE = version.PLEXPY_RELEASE_VERSION
USER_AGENT = 'Tautulli/{} ({} {})'.format(RELEASE, PLATFORM, PLATFORM_RELEASE) USER_AGENT = '{}/{} ({} {})'.format(PRODUCT, RELEASE, PLATFORM, PLATFORM_RELEASE)
DEFAULT_USER_THUMB = "interfaces/default/images/gravatar-default-80x80.png" DEFAULT_USER_THUMB = "interfaces/default/images/gravatar-default-80x80.png"
DEFAULT_POSTER_THUMB = "interfaces/default/images/poster.png" DEFAULT_POSTER_THUMB = "interfaces/default/images/poster.png"

View file

@ -39,7 +39,7 @@ class HTTPHandler(object):
else: else:
self.urls = urls self.urls = urls
self.headers = {'X-Plex-Product': 'Tautulli', self.headers = {'X-Plex-Product': plexpy.common.PRODUCT,
'X-Plex-Version': plexpy.common.RELEASE, 'X-Plex-Version': plexpy.common.RELEASE,
'X-Plex-Client-Identifier': plexpy.CONFIG.PMS_UUID, 'X-Plex-Client-Identifier': plexpy.CONFIG.PMS_UUID,
'X-Plex-Platform': plexpy.common.PLATFORM, 'X-Plex-Platform': plexpy.common.PLATFORM,