JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
login might work if node-expat did
[libre-fm-client-daemon.git] / auth.coffee
1 fs = require 'fs'
2 http = require 'http'
3 crypto = require 'crypto'
4 expat = require 'node-expat'
5
6 auth = {}
7
8 md5 = (str) ->
9         sum = crypto.createHash 'md5'
10         sum.update str
11         return sum.digest 'hex'
12
13 new_auth_token = (user, pass) ->
14         token = md5(user + md5(pass))
15         auth.user = user
16         auth.token = token
17         return token
18
19 auth_file = "#{process.env.HOME}/.libre.fm-cmus.auth"
20 save_auth = (user, pass, callback) ->
21         token = new_auth_token(user, pass)
22         text = JSON.stringify user: user, token: new_auth_token(user, pass)
23         fs.writeFile auth_file, text, 'utf8', callback
24         return token
25
26 # load login credentials from settings file
27 load_auth = (callback) ->
28         if auth.user and auth.token
29                 callback auth
30                 return
31
32         fs.readFile auth_file, 'utf8', (err, data) ->
33                 if err
34                         callback err
35                 else
36                         callback null, JSON.parse data
37
38 # login and get a session key
39 login = (callback) ->
40         load_auth (err, auth) ->
41                 return callback(err) if err?
42
43                 http.get { host: 'alpha.libre.fm', port: 80, path: "/2.0/?method=auth.getmobilesession&username=#{auth.user}&authToken=#{auth.token}"}, (res) ->
44                         if res.statusCode != 200
45                                 console.log "login response code: #{res.statusCode}"
46                                 callback "login response code: #{res.statusCode}"
47                                 return
48
49                         res.setEncoding 'utf8'
50                         body = ''
51                         res.on 'data', (chunk) ->
52                                 body += chunk
53                         res.on 'end', ->
54                                 parser = new expat.Parser 'UTF-8'
55                                 cur_tag = ''
56                                 done = false
57                                 parser.on 'startElement', (name, attrs) ->
58                                         cur_tag = name
59                                 parser.on 'text', (str) ->
60                                         if cur_tag is 'key'
61                                                 done = true
62                                                 auth.sk = str
63                                                 console.log("got key \"#{str}\"")
64                                                 callback null, str
65                                         else if cur_tag is 'error'
66                                                 done = true
67                                                 callback "login failed: #{str}"
68                                         # ignore other stuff in there
69                                 unless parser.parse body, true
70                                         done = true
71                                         callback "login server response wouldn't parse as XML."
72                                         console.log "login server sent us bad XML: #{body}"
73
74                                 unless done
75                                         callback "Couldn't understand response from login server"
76
77
78
79 exports.login = login # fixme remove this from the API and call it automatically
80 exports.new_auth_token = new_auth_token
81 exports.save_auth = save_auth