1 module hunt.framework.config.AuthUserConfig; 2 3 import hunt.framework.Init; 4 5 import std.algorithm; 6 import std.array; 7 import std.conv; 8 import std.file; 9 import std.path; 10 import std.stdio; 11 import std.range; 12 import std.string; 13 14 import hunt.logging; 15 16 17 /** 18 * Convert the permission format from Hunt to Shiro, which means that 19 * all the '.' will be replaced with the ':'. 20 */ 21 static string toShiroPermissions(string value) { 22 return value.replace('.', ':'); 23 } 24 25 /** 26 * 27 */ 28 class AuthUserConfig { 29 static class User { 30 string name; 31 string password; 32 string[] roles; 33 34 override string toString() { 35 return "name: " ~ name ~ ", role: " ~ roles.to!string(); 36 } 37 } 38 39 static class Role { 40 string name; 41 42 /** 43 * Examples: 44 * printer:query,print:lp7200 45 * 46 * See_also: 47 * https://shiro.apache.org/permissions.html 48 */ 49 string[] permissions; 50 51 override string toString() { 52 return "name: " ~ name ~ ", permissions: " ~ permissions.to!string(); 53 } 54 } 55 56 User[] users; 57 58 Role[] roles; 59 60 static AuthUserConfig load(string userConfigFile, string roleConfigFile) { 61 version(HUNT_DEBUG) { 62 tracef("Loading users from %s", userConfigFile); 63 tracef("Loading roles from %s", roleConfigFile); 64 } 65 66 AuthUserConfig config = new AuthUserConfig(); 67 68 if (exists(userConfigFile)) { 69 File f = File(userConfigFile, "r"); 70 scope(exit) f.close(); 71 72 string line; 73 while((line = f.readln()) !is null) { 74 line = line.strip(); 75 76 if(line.empty) continue; 77 78 if (line[0] == '#' || line[0] == ';') 79 continue; 80 81 string[] parts = split(line, " "); 82 if(parts.length < 2) continue; 83 84 string fieldValue; 85 string password; 86 string roles; 87 88 int fieldIndex = 1; 89 foreach(string v; parts[1..$]) { 90 fieldValue = v.strip(); 91 if(fieldValue.empty) continue; 92 93 if(fieldIndex == 1) password = fieldValue; 94 if(fieldIndex == 2) roles = fieldValue; 95 96 fieldIndex++; 97 if(fieldIndex > 2) break; 98 } 99 100 User user = new User(); 101 user.name = parts[0].strip(); 102 user.password = password; 103 user.roles = roles.split("|"); 104 105 config.users ~= user; 106 } 107 } 108 109 110 if (exists(roleConfigFile)) { 111 File f = File(roleConfigFile, "r"); 112 scope(exit) f.close(); 113 114 string line; 115 while((line = f.readln()) !is null) { 116 line = line.strip(); 117 118 if(line.empty) continue; 119 120 if (line[0] == '#' || line[0] == ';') 121 continue; 122 123 string[] parts = split(line, " "); 124 if(parts.length < 2) continue; 125 126 Role role = new Role(); 127 role.name = parts[0].strip(); 128 129 string permissions; 130 foreach(string v; parts[1..$]) { 131 permissions = v.strip(); 132 if(!permissions.empty) break; 133 } 134 135 role.permissions = permissions.split("|").map!(p => p.strip().toShiroPermissions()).array; 136 config.roles ~= role; 137 } 138 } 139 140 return config; 141 142 } 143 }