git.fiddlerwoaroof.com
Browse code

supplier and file reader classes

jbalcita authored on 23/04/2017 06:10:01
Showing 8 changed files
... ...
@@ -2,8 +2,8 @@ CXXFLAGS += -fPIC -fno-stack-protector -std=c++14
2 2
 CFLAGS += -fPIC -fno-stack-protector
3 3
 
4 4
 OBJS = dual_control.o request.o dual_control_integrate.o validator.o conversation.o user.o \
5
-	   sys_unistd.o sys_pwd.o
6
-TESTS = dual_control_test validator_test conversation_test request_test user_test
5
+	   sys_unistd.o sys_pwd.o token.o
6
+TESTS = dual_control_test validator_test conversation_test request_test user_test token_test
7 7
 TESTOBJS = $(patsubst %,%.o,$(TESTS))
8 8
 SRCS := $(OBJS:.o=.cc) $(TESTOBJS:.o=.cc)
9 9
 
... ...
@@ -71,69 +71,3 @@ conversation create_conversation (pam &pam)
71 71
 {
72 72
     return conversation (std::shared_ptr<conversation_ifc> (new impl (pam)));
73 73
 }
74
-
75
-/*
76
-int (*conv)(int num_msg, const struct pam_message **msg,
77
-                struct pam_response **resp, void *appdata_ptr)
78
-   */
79
-
80
-/*
81
-pam_token_conversation::pam_token_conversation (pam_handle_t *pamh,
82
-        const pam_p pam)
83
-{
84
-    pam_conversation_p pam_conversation;
85
-    int get_conversation_result = pam->get_conversation (pamh,
86
-                                  pam_conversation);
87
-
88
-    if (get_conversation_result != 0) {
89
-        return;
90
-    }
91
-
92
-    struct pam_message prompt;
93
-
94
-    std::string message ("Dual control token: ");
95
-
96
-    prompt.msg = const_cast<char *> (message.c_str());
97
-
98
-    prompt.msg_style = PAM_PROMPT_ECHO_OFF;
99
-
100
-    std::vector<const struct pam_message *> prompts (1);
101
-
102
-    prompts[0] = &prompt;
103
-
104
-    std::vector<struct pam_response *> answers (1);
105
-
106
-    int conversation_result = pam_conversation->conv (prompts, answers);
107
-
108
-    if (conversation_result) {
109
-        return;
110
-    }
111
-
112
-    if (answers[0]->resp_retcode) {
113
-        return;
114
-    }
115
-
116
-    std::string answer (answers[0]->resp);
117
-    std::string::iterator delim = std::find (answer.begin(), answer.end(), ':');
118
-
119
-    if (delim == answer.end()) {
120
-        return;
121
-    }
122
-
123
-    std::string user_name (answer.begin(), delim);
124
-    std::string token (delim + 1, answer.end());
125
-    user_ = user_name;
126
-    token_ = token;
127
-}
128
-
129
-std::string pam_token_conversation::token()
130
-{
131
-    return token_;
132
-}
133
-
134
-std::string pam_token_conversation::user_name()
135
-{
136
-    return user_;
137
-}
138
-*/
139
-
... ...
@@ -1,7 +1,7 @@
1 1
 /* Copyright (C) CJ Affiliate
2 2
  *
3 3
  * You may use, distribute and modify this code under  the
4
- * terms of the  GNU General Public License  version 2  or
4
+ * terms of the  GNU General Public License version 2  or
5 5
  * later.
6 6
  *
7 7
  * You should have received a copy of the license with this
... ...
@@ -9,17 +9,43 @@
9 9
  * at https://github.com/cjdev/dual-control.
10 10
  */
11 11
 
12
-#include <cstdlib>
13
-#include <cstring>
14
-#include <security/pam_modules.h>
15
-#include <pwd.h>
16
-#include <unistd.h>
17
-#include <cstdio>
18
-#include <sys/stat.h>
19 12
 #include <string>
20 13
 #include <vector>
21 14
 #include <memory>
22
-#include <fstream>
23 15
 
24
-#include "test_support.h"
16
+#include "token.h"
17
+#include "user.h"
18
+
19
+namespace
20
+{
21
+    class impl : public user_token_supplier_ifc {
22
+        private:
23
+            file_reader file_reader_;
24
+        public:
25
+            impl(file_reader &file_reader) : file_reader_(file_reader) {}
26
+            std::string token(user &user) {
27
+                std::string file_path(user.home_directory() + "/.dual_control");
28
+                std::string fetched_token(file_reader_.read(file_path));
29
+                return fetched_token;
30
+            }
31
+    };
32
+
33
+    class file_reader_impl : public file_reader_ifc {
34
+        public:
35
+            std::string read(std::string file_path) {
36
+                return file_path;
37
+            }
38
+    };
39
+}
40
+
41
+file_reader file_reader::create ()
42
+{
43
+    return file_reader (std::shared_ptr<file_reader_ifc>(new file_reader_impl ));
44
+}
45
+
46
+user_token_supplier user_token_supplier::create (file_reader &file_reader)
47
+{
48
+    return user_token_supplier (std::shared_ptr<user_token_supplier_ifc>(new impl (file_reader)));
49
+}
50
+
25 51
 
... ...
@@ -19,25 +19,52 @@
19 19
 class user_token_supplier_ifc
20 20
 {
21 21
 public:
22
-    virtual std::string token (const user &user)
22
+    virtual ~user_token_supplier_ifc() {}
23
+    virtual std::string token (user &user)
23 24
     {
24
-        return "";
25
+        return "virtual supplier";
25 26
     }
26 27
 };
27 28
 
29
+
30
+class file_reader_ifc {
31
+    public:
32
+        virtual std::string read(std::string file_path) {
33
+            return "";
34
+        }
35
+};
36
+
37
+class file_reader : public file_reader_ifc {
38
+    public:
39
+        typedef std::shared_ptr<file_reader_ifc> delegate;
40
+    private:
41
+        delegate delegate_;
42
+    public:
43
+        file_reader(delegate delegate) :
44
+            delegate_(delegate) {}
45
+        file_reader() : delegate_(delegate(new file_reader_ifc)) {}
46
+        std::string read(std::string file_path) {
47
+            return delegate_->read(file_path);
48
+        }
49
+    static file_reader create ();
50
+};
51
+
28 52
 class user_token_supplier : public user_token_supplier_ifc
29 53
 {
30
-private:
31
-    std::shared_ptr<user_token_supplier_ifc> delegate_;
32
-public:
33
-    user_token_supplier (std::shared_ptr<user_token_supplier_ifc> delegate) :
54
+    public:
55
+        typedef std::shared_ptr<user_token_supplier_ifc> delegate;
56
+    private:
57
+        delegate delegate_;
58
+    public:
59
+        user_token_supplier (delegate delegate) :
34 60
         delegate_ (delegate) {}
35
-    user_token_supplier() : user_token_supplier (
36
-            std::shared_ptr<user_token_supplier_ifc> (new user_token_supplier_ifc)) {}
37
-    std::string token (const user &user)
38
-    {
39
-        return delegate_->token (user);
40
-    }
61
+        user_token_supplier() : user_token_supplier (
62
+           delegate (new user_token_supplier_ifc)) {}
63
+        std::string token (user &user)
64
+        {
65
+            return delegate_->token (user);
66
+        }
67
+    static user_token_supplier create (file_reader &file_reader);
41 68
 };
42 69
 
43 70
 #endif
... ...
@@ -9,129 +9,63 @@
9 9
  * at https://github.com/cjdev/dual-control.
10 10
  */
11 11
 
12
+#include <memory>
12 13
 #include <cstring>
13 14
 #include <pwd.h>
14 15
 #include <cstdio>
15 16
 #include <sys/stat.h>
16 17
 
18
+
17 19
 #include "token.h"
18 20
 #include "test_util.h"
19
-
20
-const char *fake_user = "";
21
-const char *fake_user_token = "";
22
-
23
-// all the fake system calls
24
-const char *fake_home_dir = "";
25
-int fake_getpwnam_r (const char *nam, struct passwd *pwd, char *buffer,
26
-                     size_t bufsize, struct passwd **result)
27
-{
28
-    strcpy (buffer, fake_home_dir);
29
-    pwd->pw_dir = buffer;
30
-    int ok = !strcmp (nam, fake_user);
31
-    *result = ok ? pwd : 0;
32
-    return !ok;
33
-}
34
-
35
-const char *fake_stat_path = "";
36
-int fake_stat (const char *path, struct stat *stat)
37
-{
38
-    return (strcmp (fake_stat_path, path));
39
-}
40
-
41
-const char *fake_fopen_path = "";
42
-const char *fake_fopen_mode = "";
43
-FILE *_fhandle = 0;
44
-FILE *fake_fopen (const char *path, const char *mode)
45
-{
46
-    static FILE handle;
47
-    int path_matches = !strcmp (fake_fopen_path, path);
48
-    int mode_matches = !strcmp (fake_fopen_mode, mode);
49
-
50
-    if (path_matches && mode_matches) {
51
-        _fhandle = &handle;
52
-        return &handle;
53
-    } else {
54
-        _fhandle = 0;
55
-        return 0;
56
-    }
57
-}
58
-
59
-char *fake_fgets (char *buf, int n, FILE *fp)
60
-{
61
-    if (_fhandle == fp && fp != 0) {
62
-        strncpy (buf, fake_user_token, n - 1);
63
-        return buf;
64
-    } else {
65
-        return 0;
66
-    }
67
-}
68
-
69
-int fake_fclose (FILE *fp)
70
-{
71
-    return 0;
72
-}
73
-
74
-// STDIO
75
-
76
-RESET_VARS_START
77
-fake_user = "msmith";
78
-fake_user_token = "123456";
79
-fake_home_dir = "/home/msmith";
80
-fake_stat_path = "/home/msmith/.dual_control";
81
-fake_fopen_path = fake_stat_path;
82
-fake_fopen_mode = "r";
83
-RESET_VARS_END
84
-
85
-int validate_compares_to_user_token()
86
-{
87
-
88
-    // given
89
-
90
-    // when
91
-    int valid = validate_token ("msmith", "123456");
92
-
93
-    // then
94
-    check (valid, "expected result to be valid");
95
-
96
-    succeed();
97
-
98
-}
99
-
100
-int validates_from_the_right_user()
101
-{
21
+#include "user.h"
22
+
23
+class fake_file_reader : public file_reader_ifc {
24
+    public:
25
+        std::string read(std::string file_path) {
26
+            return file_path;
27
+        }
28
+};
29
+
30
+class fake_user : public user_ifc {
31
+    private:
32
+        std::string home_directory_;
33
+    public:
34
+        fake_user(std::string &user_name) :
35
+            home_directory_("home/" + user_name) {
36
+            }
37
+        std::string home_directory() {
38
+            return home_directory_;
39
+        }
40
+};
41
+
42
+int reads_from_the_right_file () {
102 43
     //given
44
+    file_reader test_file_reader(file_reader::delegate(new fake_file_reader));
45
+    std::string user_name = "user";
46
+    std::string expected = "home/" + user_name + "/.dual_control";
47
+    user test_user(user::delegate(new fake_user(user_name)));
48
+    user_token_supplier supplier(user_token_supplier::create(test_file_reader));
103 49
 
104 50
     //when
105
-    int valid = validate_token ("jbalcita", "12346");
51
+    std::string actual = supplier.token(test_user);
106 52
 
107 53
     //then
108
-    check (!valid, "expected result to be invalid");
54
+    check(actual == expected, "read wrong file");
109 55
     succeed();
110 56
 }
111 57
 
112
-int validates_user_specific_token()
113
-{
114
-    //given
115 58
 
116
-    //when
117
-    int valid = validate_token ("msmith", "654321");
118 59
 
119
-    //then
120
-    check (!valid, "expected result to be invalid");
121
-    succeed();
122
-}
60
+RESET_VARS_START
61
+RESET_VARS_END
123 62
 
124
-int runtests()
125
-{
126
-    test (validate_compares_to_user_token);
127
-    test (validates_from_the_right_user);
128
-    test (validates_user_specific_token);
63
+int run_tests() {
64
+    test(reads_from_the_right_file);
129 65
     succeed();
130 66
 }
131 67
 
132
-int main (int argc, char **argv)
133
-{
134
-    int rval = !runtests();
135
-    return rval;
68
+int main(int argc, char *argv[]) {
69
+    return !run_tests();
136 70
 }
137 71
 
... ...
@@ -11,6 +11,7 @@
11 11
 
12 12
 #include <memory>
13 13
 #include <vector>
14
+#include <iostream>
14 15
 
15 16
 #include "user.h"
16 17
 #include "sys_unistd.h"
... ...
@@ -18,6 +19,19 @@
18 19
 
19 20
 namespace
20 21
 {
22
+class user_impl : public user_ifc {
23
+    private:
24
+        std::string home_directory_;
25
+        std::string user_name_;
26
+    public:
27
+        user_impl(const passwd user_info) :
28
+            home_directory_(std::string(user_info.pw_dir)),
29
+            user_name_(std::string(user_info.pw_name)) {}
30
+        std::string home_directory() {
31
+            return home_directory_;
32
+        }
33
+};
34
+
21 35
 class directory_impl : public directory_ifc
22 36
 {
23 37
 private:
... ...
@@ -35,7 +49,7 @@ public:
35 49
         std::vector<user> return_value;
36 50
 
37 51
         if (!result && found_passwd) {
38
-            return_value.push_back (user());
52
+            return_value.push_back (std::shared_ptr<user_ifc>(new user_impl(sys_passwd)));
39 53
         }
40 54
 
41 55
         return return_value;
... ...
@@ -14,7 +14,7 @@
14 14
 #include <vector>
15 15
 #include <string>
16 16
 #include <memory>
17
-
17
+#include <iostream>
18 18
 #include "sys_unistd.h"
19 19
 #include "sys_pwd.h"
20 20
 
... ...
@@ -22,15 +22,25 @@ class user_ifc
22 22
 {
23 23
 public:
24 24
     virtual ~user_ifc() {}
25
+    virtual std::string home_directory() {
26
+        return "virtual";
27
+    }
25 28
 };
26 29
 
27 30
 class user : public user_ifc
28 31
 {
29
-private:
30
-    std::shared_ptr<user_ifc> delegate_;
31
-public:
32
-    user (std::shared_ptr<user_ifc> delegate) : delegate_ (delegate) {}
33
-    user() : user (std::shared_ptr<user_ifc> (new user_ifc)) {}
32
+    public:
33
+        typedef std::shared_ptr<user_ifc> delegate;
34
+    private:
35
+        delegate delegate_;
36
+    public:
37
+        user (delegate delegate) : delegate_ (delegate) {
38
+        }
39
+        user() : user (delegate (new user_ifc)) {}
40
+        std::string home_directory() {
41
+            return delegate_-> home_directory();
42
+        }
43
+    static user create (const passwd &passwd);
34 44
 };
35 45
 
36 46
 class directory_ifc
... ...
@@ -34,7 +34,6 @@ public:
34 34
         if (user_name == user_name_) {
35 35
             result.push_back (user());
36 36
         }
37
-
38 37
         return result;
39 38
     }
40 39
 };
... ...
@@ -46,7 +45,7 @@ private:
46 45
 public:
47 46
     fake_user_token_supplier (const std::string &token) : token_ (token) {}
48 47
     fake_user_token_supplier() : token_ ("_NOT_A_TOKEN") {}
49
-    virtual std::string token (const user &user)
48
+    std::string token (user &user)
50 49
     {
51 50
         return token_;
52 51
     }