{"action":"created","comment":{"url":"https://api.github.com/repos/mendersoftware/mender/pulls/comments/66930395","id":66930395,"diff_hunk":"@@ -0,0 +1,122 @@\n+// Copyright 2016 Mender Software AS\n+//\n+//    Licensed under the Apache License, Version 2.0 (the \"License\");\n+//    you may not use this file except in compliance with the License.\n+//    You may obtain a copy of the License at\n+//\n+//        http://www.apache.org/licenses/LICENSE-2.0\n+//\n+//    Unless required by applicable law or agreed to in writing, software\n+//    distributed under the License is distributed on an \"AS IS\" BASIS,\n+//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+//    See the License for the specific language governing permissions and\n+//    limitations under the License.\n+package main\n+\n+import (\n+\t\"bytes\"\n+\t\"encoding/json\"\n+\t\"io/ioutil\"\n+\t\"net/http\"\n+\n+\t\"github.com/mendersoftware/log\"\n+\t\"github.com/pkg/errors\"\n+)\n+\n+type AuthGetter interface {\n+\tRequest(identity, deviceID string) (interface{}, error)\n+}\n+\n+// source of authorization data\n+type AuthDataProvider interface {\n+\t// returns device public key\n+\tPubkey() (string, error)\n+\t// returns tenant token\n+\tToken() (string, error)\n+\t// returns identity data\n+\tIdentityData() (interface{}, error)\n+}\n+\n+type AuthClient struct {\n+\tclient *http.Client\n+}\n+\n+func NewAuthClient(conf httpsClientConfig) (*AuthClient, error) {\n+\tclient, err := NewHttpClient(conf)\n+\tif client == nil {\n+\t\treturn nil, errors.Wrap(err, \"failed to create auth client HTTP client\")\n+\t}\n+\n+\tau := AuthClient{\n+\t\tclient: client,\n+\t}\n+\treturn &au, nil\n+}\n+\n+func (u *AuthClient) Request(server string, datasrc AuthDataProvider) (interface{}, error) {\n+\n+\treq, err := makeAuthRequest(server, datasrc)\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to build auth request\")\n+\t}\n+\n+\tlog.Debugf(\"making authorization request to server %s with req: %s\", server, req)\n+\trsp, err := u.client.Do(req)\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to execute request\")\n+\t}\n+\tdefer rsp.Body.Close()\n+\n+\tlog.Debugf(\"receive response data\")\n+\tdata, err := ioutil.ReadAll(rsp.Body)\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to receive response data\")\n+\t}\n+\n+\t// validate response\n+\tlog.Debugf(\"received response data %v\", data)\n+\n+\treturn data, nil\n+}\n+\n+type authReqData struct {\n+\tIdData      interface{} `json:\"id_data\"`\n+\tTenantToken string      `json:\"tenant_token\"`\n+\tPubkey      string      `json:\"pubkey\"`\n+}\n+\n+func makeAuthRequest(server string, datasrc AuthDataProvider) (*http.Request, error) {\n+\turl := buildURL(server) + \"/v0.1/auth_requests\"\n+\n+\tvar err error\n+\tauthd := authReqData{}\n+\n+\tauthd.IdData, err = datasrc.IdentityData()\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to obtain identity data\")\n+\t}\n+\n+\tauthd.TenantToken, err = datasrc.Token()\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to obtain tenant token\")\n+\t}\n+\n+\tauthd.Pubkey, err = datasrc.Pubkey()\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to obtain device public key\")\n+\t}\n+\n+\tdatabuf := &bytes.Buffer{}\n+\tenc := json.NewEncoder(databuf)\n+\n+\terr = enc.Encode(&authd)\n+\tif err != nil {\n+\t\treturn nil, errors.Wrapf(err, \"failed to encode auth request\")\n+\t}\n+\n+\treq, err := http.NewRequest(http.MethodGet, url, databuf)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}","path":"client_auth.go","position":120,"original_position":120,"commit_id":"2139bf44a7ba4e67dd724ab7d5bd94e2803ef21c","original_commit_id":"2139bf44a7ba4e67dd724ab7d5bd94e2803ef21c","user":{"login":"pasinskim","id":6329055,"avatar_url":"https://avatars.githubusercontent.com/u/6329055?v=3","gravatar_id":"","url":"https://api.github.com/users/pasinskim","html_url":"https://github.com/pasinskim","followers_url":"https://api.github.com/users/pasinskim/followers","following_url":"https://api.github.com/users/pasinskim/following{/other_user}","gists_url":"https://api.github.com/users/pasinskim/gists{/gist_id}","starred_url":"https://api.github.com/users/pasinskim/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pasinskim/subscriptions","organizations_url":"https://api.github.com/users/pasinskim/orgs","repos_url":"https://api.github.com/users/pasinskim/repos","events_url":"https://api.github.com/users/pasinskim/events{/privacy}","received_events_url":"https://api.github.com/users/pasinskim/received_events","type":"User","site_admin":false},"body":"Maybe some debug log `auth request created...`?","created_at":"2016-06-14T08:45:07Z","updated_at":"2016-06-14T08:45:07Z","html_url":"https://github.com/mendersoftware/mender/pull/68#discussion_r66930395","pull_request_url":"https://api.github.com/repos/mendersoftware/mender/pulls/68","_links":{"self":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/comments/66930395"},"html":{"href":"https://github.com/mendersoftware/mender/pull/68#discussion_r66930395"},"pull_request":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/68"}}},"pull_request":{"url":"https://api.github.com/repos/mendersoftware/mender/pulls/68","id":73693436,"html_url":"https://github.com/mendersoftware/mender/pull/68","diff_url":"https://github.com/mendersoftware/mender/pull/68.diff","patch_url":"https://github.com/mendersoftware/mender/pull/68.patch","issue_url":"https://api.github.com/repos/mendersoftware/mender/issues/68","number":68,"state":"open","locked":false,"title":"client state refactoring & basic authorization setup","user":{"login":"bboozzoo","id":41870,"avatar_url":"https://avatars.githubusercontent.com/u/41870?v=3","gravatar_id":"","url":"https://api.github.com/users/bboozzoo","html_url":"https://github.com/bboozzoo","followers_url":"https://api.github.com/users/bboozzoo/followers","following_url":"https://api.github.com/users/bboozzoo/following{/other_user}","gists_url":"https://api.github.com/users/bboozzoo/gists{/gist_id}","starred_url":"https://api.github.com/users/bboozzoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bboozzoo/subscriptions","organizations_url":"https://api.github.com/users/bboozzoo/orgs","repos_url":"https://api.github.com/users/bboozzoo/repos","events_url":"https://api.github.com/users/bboozzoo/events{/privacy}","received_events_url":"https://api.github.com/users/bboozzoo/received_events","type":"User","site_admin":false},"body":"While working on authorization implementation it turned out that the client code needs a refactoring, otherwise it would be hard to go through authorization steps in a clean manner.\r\n\r\nThe patch series introduces some major changes to the agent code, in rough detail these are:\r\n* do away with inheritance (or struct/interface embeddeding) in favor of composition where possible; for instance `menderDaemon` does not need to export any interfaces, while `mender` should only export minimal set of interfaces\r\n* introduce a single `Controler` interface\r\n* split `Client` and `UpdateClient` to separate interfaces\r\n* use a state pattern to implement client states, separates controler from actual state execution; operations on controler have been nicely moved to states\r\n* introduction of `menderError` interface; this extends the `error` with extra methods for querying whether an error is fatal or not (used by error state handler)\r\n \r\nIntrouce some helpers/interfaces for implementation of authorization flow, these are:\r\n* `IdentityDataGetter` for obtaining device identity information\r\n* `AuthClient` actual client to the authorization service\r\n* `FileSeqnum`, `Seqnum` number sequence generators with file storage (required for keeping track of auth request sequence numbers)\r\n* `Store` a  generic storage wrapper\r\n\r\nSince the authorization work is kind of separate from the rest, I can put that into a different branch and open a PR from that branch after we've merged the generic changes form this PR.\r\n\r\n@pasinskim @kacf ","created_at":"2016-06-14T07:42:08Z","updated_at":"2016-06-14T08:45:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c501560ed89b38917cc2a45f0da9e47232bcd32b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/mendersoftware/mender/pulls/68/commits","review_comments_url":"https://api.github.com/repos/mendersoftware/mender/pulls/68/comments","review_comment_url":"https://api.github.com/repos/mendersoftware/mender/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mendersoftware/mender/issues/68/comments","statuses_url":"https://api.github.com/repos/mendersoftware/mender/statuses/2139bf44a7ba4e67dd724ab7d5bd94e2803ef21c","head":{"label":"bboozzoo:bboozzoo/bootstrap-states","ref":"bboozzoo/bootstrap-states","sha":"2139bf44a7ba4e67dd724ab7d5bd94e2803ef21c","user":{"login":"bboozzoo","id":41870,"avatar_url":"https://avatars.githubusercontent.com/u/41870?v=3","gravatar_id":"","url":"https://api.github.com/users/bboozzoo","html_url":"https://github.com/bboozzoo","followers_url":"https://api.github.com/users/bboozzoo/followers","following_url":"https://api.github.com/users/bboozzoo/following{/other_user}","gists_url":"https://api.github.com/users/bboozzoo/gists{/gist_id}","starred_url":"https://api.github.com/users/bboozzoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bboozzoo/subscriptions","organizations_url":"https://api.github.com/users/bboozzoo/orgs","repos_url":"https://api.github.com/users/bboozzoo/repos","events_url":"https://api.github.com/users/bboozzoo/events{/privacy}","received_events_url":"https://api.github.com/users/bboozzoo/received_events","type":"User","site_admin":false},"repo":{"id":58195891,"name":"mender","full_name":"bboozzoo/mender","owner":{"login":"bboozzoo","id":41870,"avatar_url":"https://avatars.githubusercontent.com/u/41870?v=3","gravatar_id":"","url":"https://api.github.com/users/bboozzoo","html_url":"https://github.com/bboozzoo","followers_url":"https://api.github.com/users/bboozzoo/followers","following_url":"https://api.github.com/users/bboozzoo/following{/other_user}","gists_url":"https://api.github.com/users/bboozzoo/gists{/gist_id}","starred_url":"https://api.github.com/users/bboozzoo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bboozzoo/subscriptions","organizations_url":"https://api.github.com/users/bboozzoo/orgs","repos_url":"https://api.github.com/users/bboozzoo/repos","events_url":"https://api.github.com/users/bboozzoo/events{/privacy}","received_events_url":"https://api.github.com/users/bboozzoo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bboozzoo/mender","description":"Mender over-the-air software updates.","fork":true,"url":"https://api.github.com/repos/bboozzoo/mender","forks_url":"https://api.github.com/repos/bboozzoo/mender/forks","keys_url":"https://api.github.com/repos/bboozzoo/mender/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bboozzoo/mender/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bboozzoo/mender/teams","hooks_url":"https://api.github.com/repos/bboozzoo/mender/hooks","issue_events_url":"https://api.github.com/repos/bboozzoo/mender/issues/events{/number}","events_url":"https://api.github.com/repos/bboozzoo/mender/events","assignees_url":"https://api.github.com/repos/bboozzoo/mender/assignees{/user}","branches_url":"https://api.github.com/repos/bboozzoo/mender/branches{/branch}","tags_url":"https://api.github.com/repos/bboozzoo/mender/tags","blobs_url":"https://api.github.com/repos/bboozzoo/mender/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bboozzoo/mender/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bboozzoo/mender/git/refs{/sha}","trees_url":"https://api.github.com/repos/bboozzoo/mender/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bboozzoo/mender/statuses/{sha}","languages_url":"https://api.github.com/repos/bboozzoo/mender/languages","stargazers_url":"https://api.github.com/repos/bboozzoo/mender/stargazers","contributors_url":"https://api.github.com/repos/bboozzoo/mender/contributors","subscribers_url":"https://api.github.com/repos/bboozzoo/mender/subscribers","subscription_url":"https://api.github.com/repos/bboozzoo/mender/subscription","commits_url":"https://api.github.com/repos/bboozzoo/mender/commits{/sha}","git_commits_url":"https://api.github.com/repos/bboozzoo/mender/git/commits{/sha}","comments_url":"https://api.github.com/repos/bboozzoo/mender/comments{/number}","issue_comment_url":"https://api.github.com/repos/bboozzoo/mender/issues/comments{/number}","contents_url":"https://api.github.com/repos/bboozzoo/mender/contents/{+path}","compare_url":"https://api.github.com/repos/bboozzoo/mender/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bboozzoo/mender/merges","archive_url":"https://api.github.com/repos/bboozzoo/mender/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bboozzoo/mender/downloads","issues_url":"https://api.github.com/repos/bboozzoo/mender/issues{/number}","pulls_url":"https://api.github.com/repos/bboozzoo/mender/pulls{/number}","milestones_url":"https://api.github.com/repos/bboozzoo/mender/milestones{/number}","notifications_url":"https://api.github.com/repos/bboozzoo/mender/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bboozzoo/mender/labels{/name}","releases_url":"https://api.github.com/repos/bboozzoo/mender/releases{/id}","deployments_url":"https://api.github.com/repos/bboozzoo/mender/deployments","created_at":"2016-05-06T09:20:01Z","updated_at":"2016-05-06T09:20:02Z","pushed_at":"2016-06-14T07:29:14Z","git_url":"git://github.com/bboozzoo/mender.git","ssh_url":"git@github.com:bboozzoo/mender.git","clone_url":"https://github.com/bboozzoo/mender.git","svn_url":"https://github.com/bboozzoo/mender","homepage":"https://mender.io","size":844,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"mendersoftware:master","ref":"master","sha":"476afbc703546d668fc7e4a215c958cc1c291192","user":{"login":"mendersoftware","id":15040539,"avatar_url":"https://avatars.githubusercontent.com/u/15040539?v=3","gravatar_id":"","url":"https://api.github.com/users/mendersoftware","html_url":"https://github.com/mendersoftware","followers_url":"https://api.github.com/users/mendersoftware/followers","following_url":"https://api.github.com/users/mendersoftware/following{/other_user}","gists_url":"https://api.github.com/users/mendersoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/mendersoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mendersoftware/subscriptions","organizations_url":"https://api.github.com/users/mendersoftware/orgs","repos_url":"https://api.github.com/users/mendersoftware/repos","events_url":"https://api.github.com/users/mendersoftware/events{/privacy}","received_events_url":"https://api.github.com/users/mendersoftware/received_events","type":"Organization","site_admin":false},"repo":{"id":47542798,"name":"mender","full_name":"mendersoftware/mender","owner":{"login":"mendersoftware","id":15040539,"avatar_url":"https://avatars.githubusercontent.com/u/15040539?v=3","gravatar_id":"","url":"https://api.github.com/users/mendersoftware","html_url":"https://github.com/mendersoftware","followers_url":"https://api.github.com/users/mendersoftware/followers","following_url":"https://api.github.com/users/mendersoftware/following{/other_user}","gists_url":"https://api.github.com/users/mendersoftware/gists{/gist_id}","starred_url":"https://api.github.com/users/mendersoftware/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mendersoftware/subscriptions","organizations_url":"https://api.github.com/users/mendersoftware/orgs","repos_url":"https://api.github.com/users/mendersoftware/repos","events_url":"https://api.github.com/users/mendersoftware/events{/privacy}","received_events_url":"https://api.github.com/users/mendersoftware/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mendersoftware/mender","description":"Mender over-the-air software updates.","fork":false,"url":"https://api.github.com/repos/mendersoftware/mender","forks_url":"https://api.github.com/repos/mendersoftware/mender/forks","keys_url":"https://api.github.com/repos/mendersoftware/mender/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mendersoftware/mender/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mendersoftware/mender/teams","hooks_url":"https://api.github.com/repos/mendersoftware/mender/hooks","issue_events_url":"https://api.github.com/repos/mendersoftware/mender/issues/events{/number}","events_url":"https://api.github.com/repos/mendersoftware/mender/events","assignees_url":"https://api.github.com/repos/mendersoftware/mender/assignees{/user}","branches_url":"https://api.github.com/repos/mendersoftware/mender/branches{/branch}","tags_url":"https://api.github.com/repos/mendersoftware/mender/tags","blobs_url":"https://api.github.com/repos/mendersoftware/mender/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mendersoftware/mender/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mendersoftware/mender/git/refs{/sha}","trees_url":"https://api.github.com/repos/mendersoftware/mender/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mendersoftware/mender/statuses/{sha}","languages_url":"https://api.github.com/repos/mendersoftware/mender/languages","stargazers_url":"https://api.github.com/repos/mendersoftware/mender/stargazers","contributors_url":"https://api.github.com/repos/mendersoftware/mender/contributors","subscribers_url":"https://api.github.com/repos/mendersoftware/mender/subscribers","subscription_url":"https://api.github.com/repos/mendersoftware/mender/subscription","commits_url":"https://api.github.com/repos/mendersoftware/mender/commits{/sha}","git_commits_url":"https://api.github.com/repos/mendersoftware/mender/git/commits{/sha}","comments_url":"https://api.github.com/repos/mendersoftware/mender/comments{/number}","issue_comment_url":"https://api.github.com/repos/mendersoftware/mender/issues/comments{/number}","contents_url":"https://api.github.com/repos/mendersoftware/mender/contents/{+path}","compare_url":"https://api.github.com/repos/mendersoftware/mender/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mendersoftware/mender/merges","archive_url":"https://api.github.com/repos/mendersoftware/mender/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mendersoftware/mender/downloads","issues_url":"https://api.github.com/repos/mendersoftware/mender/issues{/number}","pulls_url":"https://api.github.com/repos/mendersoftware/mender/pulls{/number}","milestones_url":"https://api.github.com/repos/mendersoftware/mender/milestones{/number}","notifications_url":"https://api.github.com/repos/mendersoftware/mender/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mendersoftware/mender/labels{/name}","releases_url":"https://api.github.com/repos/mendersoftware/mender/releases{/id}","deployments_url":"https://api.github.com/repos/mendersoftware/mender/deployments","created_at":"2015-12-07T09:36:43Z","updated_at":"2016-05-11T10:44:26Z","pushed_at":"2016-06-14T07:42:08Z","git_url":"git://github.com/mendersoftware/mender.git","ssh_url":"git@github.com:mendersoftware/mender.git","clone_url":"https://github.com/mendersoftware/mender.git","svn_url":"https://github.com/mendersoftware/mender","homepage":"https://mender.io","size":798,"stargazers_count":10,"watchers_count":10,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":10,"mirror_url":null,"open_issues_count":2,"forks":10,"open_issues":2,"watchers":10,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/68"},"html":{"href":"https://github.com/mendersoftware/mender/pull/68"},"issue":{"href":"https://api.github.com/repos/mendersoftware/mender/issues/68"},"comments":{"href":"https://api.github.com/repos/mendersoftware/mender/issues/68/comments"},"review_comments":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/68/comments"},"review_comment":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mendersoftware/mender/pulls/68/commits"},"statuses":{"href":"https://api.github.com/repos/mendersoftware/mender/statuses/2139bf44a7ba4e67dd724ab7d5bd94e2803ef21c"}}}}
{"actor":{"display_login":"pasinskim"}}