Fossil SCM
Add the login-group command for managing login groups from the command-line.
Commit
c3ba504d5c85bebffd5d7fa1eb26f94daacfb77dc104d974539ecd06b1951f1e
Parent
20abe259639742f…
2 files changed
+96
-12
+1
-1
+96
-12
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -1821,20 +1821,20 @@ | ||
| 1821 | 1821 | ** |
| 1822 | 1822 | ** If problems arise, leave an error message in *pzErrMsg. |
| 1823 | 1823 | */ |
| 1824 | 1824 | void login_group_join( |
| 1825 | 1825 | const char *zRepo, /* Repository file in the login group */ |
| 1826 | + int bPwRequired, /* True if the login,password is required */ | |
| 1826 | 1827 | const char *zLogin, /* Login name for the other repo */ |
| 1827 | 1828 | const char *zPassword, /* Password to prove we are authorized to join */ |
| 1828 | 1829 | const char *zNewName, /* Name of new login group if making a new one */ |
| 1829 | 1830 | char **pzErrMsg /* Leave an error message here */ |
| 1830 | 1831 | ){ |
| 1831 | 1832 | Blob fullName; /* Blob for finding full pathnames */ |
| 1832 | 1833 | sqlite3 *pOther; /* The other repository */ |
| 1833 | 1834 | int rc; /* Return code from sqlite3 functions */ |
| 1834 | 1835 | char *zOtherProjCode; /* Project code for pOther */ |
| 1835 | - char *zPwHash; /* Password hash on pOther */ | |
| 1836 | 1836 | char *zSelfRepo; /* Name of our repository */ |
| 1837 | 1837 | char *zSelfLabel; /* Project-name for our repository */ |
| 1838 | 1838 | char *zSelfProjCode; /* Our project-code */ |
| 1839 | 1839 | char *zSql; /* SQL to run on all peers */ |
| 1840 | 1840 | const char *zSelf; /* The ATTACH name of our repository */ |
| @@ -1886,21 +1886,24 @@ | ||
| 1886 | 1886 | ** valid and has Setup permission. |
| 1887 | 1887 | */ |
| 1888 | 1888 | db_attach(zRepo, "other"); |
| 1889 | 1889 | zOtherProjCode = db_text("x", "SELECT value FROM other.config" |
| 1890 | 1890 | " WHERE name='project-code'"); |
| 1891 | - zPwHash = sha1_shared_secret(zPassword, zLogin, zOtherProjCode); | |
| 1892 | - if( !db_exists( | |
| 1893 | - "SELECT 1 FROM other.user" | |
| 1894 | - " WHERE login=%Q AND cap GLOB '*s*'" | |
| 1895 | - " AND (pw=%Q OR pw=%Q)", | |
| 1896 | - zLogin, zPassword, zPwHash) | |
| 1897 | - ){ | |
| 1898 | - db_detach("other"); | |
| 1899 | - *pzErrMsg = "The supplied username/password does not correspond to a" | |
| 1900 | - " user Setup permission on the other repository."; | |
| 1901 | - return; | |
| 1891 | + if( bPwRequired ){ | |
| 1892 | + char *zPwHash; /* Password hash on pOther */ | |
| 1893 | + zPwHash = sha1_shared_secret(zPassword, zLogin, zOtherProjCode); | |
| 1894 | + if( !db_exists( | |
| 1895 | + "SELECT 1 FROM other.user" | |
| 1896 | + " WHERE login=%Q AND cap GLOB '*s*'" | |
| 1897 | + " AND (pw=%Q OR pw=%Q)", | |
| 1898 | + zLogin, zPassword, zPwHash) | |
| 1899 | + ){ | |
| 1900 | + db_detach("other"); | |
| 1901 | + *pzErrMsg = "The supplied username/password does not correspond to a" | |
| 1902 | + " user Setup permission on the other repository."; | |
| 1903 | + return; | |
| 1904 | + } | |
| 1902 | 1905 | } |
| 1903 | 1906 | |
| 1904 | 1907 | /* Create all the necessary CONFIG table entries on both the |
| 1905 | 1908 | ** other repository and on our own repository. |
| 1906 | 1909 | */ |
| @@ -1967,6 +1970,87 @@ | ||
| 1967 | 1970 | db_multi_exec( |
| 1968 | 1971 | "DELETE FROM config " |
| 1969 | 1972 | " WHERE name GLOB 'peer-*'" |
| 1970 | 1973 | " OR name GLOB 'login-group-*';" |
| 1971 | 1974 | ); |
| 1975 | +} | |
| 1976 | + | |
| 1977 | +/* | |
| 1978 | +** COMMAND: login-group | |
| 1979 | +** | |
| 1980 | +** Usage: %fossil login-group | |
| 1981 | +** or: %fossil login-group join REPO [-name NAME] | |
| 1982 | +** or: %fossil login-group leave | |
| 1983 | +** | |
| 1984 | +** With no arguments, this command shows the login-group to which the | |
| 1985 | +** repository belongs. | |
| 1986 | +** | |
| 1987 | +** The "join" command adds this repository to login group to which REPO | |
| 1988 | +** belongs, or creates a new login group between itself and REPO if REPO | |
| 1989 | +** does not already belong to a login-group. When creating a new login- | |
| 1990 | +** group, the name of the new group is determined by the "--name" option. | |
| 1991 | +** | |
| 1992 | +** The "leave" command takes the repository out of whatever login group | |
| 1993 | +** it is currently a part of. | |
| 1994 | +** | |
| 1995 | +** About Login Groups: | |
| 1996 | +** | |
| 1997 | +** A login-group is a set of repositories that share user credentials. | |
| 1998 | +** If a user is logged into one member of the group, then that user can | |
| 1999 | +** access any other group member as long as they have an entry in the | |
| 2000 | +** USER table of that member. If a user changes their password using | |
| 2001 | +** web interface, their password is also automatically changed in every | |
| 2002 | +** other member of the login group. | |
| 2003 | +*/ | |
| 2004 | +void login_group_command(void){ | |
| 2005 | + const char *zLGName; | |
| 2006 | + const char *zCmd; | |
| 2007 | + int nCmd; | |
| 2008 | + Stmt q; | |
| 2009 | + db_find_and_open_repository(0,0); | |
| 2010 | + if( g.argc>2 ){ | |
| 2011 | + zCmd = g.argv[2]; | |
| 2012 | + nCmd = (int)strlen(zCmd); | |
| 2013 | + if( strncmp(zCmd,"join",nCmd)==0 && nCmd>=1 ){ | |
| 2014 | + const char *zNewName = find_option("name",0,1); | |
| 2015 | + const char *zOther; | |
| 2016 | + char *zErr = 0; | |
| 2017 | + verify_all_options(); | |
| 2018 | + if( g.argc!=4 ){ | |
| 2019 | + fossil_fatal("unknown extra arguments to \"login-group add\""); | |
| 2020 | + } | |
| 2021 | + zOther = g.argv[3]; | |
| 2022 | + login_group_join(zOther,0,0,0,zNewName,&zErr); | |
| 2023 | + if( zErr ){ | |
| 2024 | + fossil_fatal("%s", zErr); | |
| 2025 | + } | |
| 2026 | + }else if( strncmp(zCmd,"leave",nCmd)==0 && nCmd>=1 ){ | |
| 2027 | + verify_all_options(); | |
| 2028 | + if( g.argc!=3 ){ | |
| 2029 | + fossil_fatal("unknown extra arguments to \"login-group leave\""); | |
| 2030 | + } | |
| 2031 | + zLGName = login_group_name(); | |
| 2032 | + if( zLGName ){ | |
| 2033 | + char *zErr = 0; | |
| 2034 | + fossil_print("Leaving login-group \"%s\"\n", zLGName); | |
| 2035 | + login_group_leave(&zErr); | |
| 2036 | + return; | |
| 2037 | + } | |
| 2038 | + }else{ | |
| 2039 | + fossil_fatal("unknown command \"%s\" - should be \"add\" or \"leave\"", | |
| 2040 | + zCmd); | |
| 2041 | + } | |
| 2042 | + } | |
| 2043 | + /* Show the current login group information */ | |
| 2044 | + zLGName = login_group_name(); | |
| 2045 | + if( zLGName==0 ){ | |
| 2046 | + fossil_print("Not currently a part of any login-group\n"); | |
| 2047 | + return; | |
| 2048 | + } | |
| 2049 | + fossil_print("Now part of login-group \"%s\" with:\n", zLGName); | |
| 2050 | + db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-name-%%'"); | |
| 2051 | + while( db_step(&q)==SQLITE_ROW ){ | |
| 2052 | + fossil_print(" %s\n", db_column_text(&q,0)); | |
| 2053 | + } | |
| 2054 | + db_finalize(&q); | |
| 2055 | + | |
| 1972 | 2056 | } |
| 1973 | 2057 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1821,20 +1821,20 @@ | |
| 1821 | ** |
| 1822 | ** If problems arise, leave an error message in *pzErrMsg. |
| 1823 | */ |
| 1824 | void login_group_join( |
| 1825 | const char *zRepo, /* Repository file in the login group */ |
| 1826 | const char *zLogin, /* Login name for the other repo */ |
| 1827 | const char *zPassword, /* Password to prove we are authorized to join */ |
| 1828 | const char *zNewName, /* Name of new login group if making a new one */ |
| 1829 | char **pzErrMsg /* Leave an error message here */ |
| 1830 | ){ |
| 1831 | Blob fullName; /* Blob for finding full pathnames */ |
| 1832 | sqlite3 *pOther; /* The other repository */ |
| 1833 | int rc; /* Return code from sqlite3 functions */ |
| 1834 | char *zOtherProjCode; /* Project code for pOther */ |
| 1835 | char *zPwHash; /* Password hash on pOther */ |
| 1836 | char *zSelfRepo; /* Name of our repository */ |
| 1837 | char *zSelfLabel; /* Project-name for our repository */ |
| 1838 | char *zSelfProjCode; /* Our project-code */ |
| 1839 | char *zSql; /* SQL to run on all peers */ |
| 1840 | const char *zSelf; /* The ATTACH name of our repository */ |
| @@ -1886,21 +1886,24 @@ | |
| 1886 | ** valid and has Setup permission. |
| 1887 | */ |
| 1888 | db_attach(zRepo, "other"); |
| 1889 | zOtherProjCode = db_text("x", "SELECT value FROM other.config" |
| 1890 | " WHERE name='project-code'"); |
| 1891 | zPwHash = sha1_shared_secret(zPassword, zLogin, zOtherProjCode); |
| 1892 | if( !db_exists( |
| 1893 | "SELECT 1 FROM other.user" |
| 1894 | " WHERE login=%Q AND cap GLOB '*s*'" |
| 1895 | " AND (pw=%Q OR pw=%Q)", |
| 1896 | zLogin, zPassword, zPwHash) |
| 1897 | ){ |
| 1898 | db_detach("other"); |
| 1899 | *pzErrMsg = "The supplied username/password does not correspond to a" |
| 1900 | " user Setup permission on the other repository."; |
| 1901 | return; |
| 1902 | } |
| 1903 | |
| 1904 | /* Create all the necessary CONFIG table entries on both the |
| 1905 | ** other repository and on our own repository. |
| 1906 | */ |
| @@ -1967,6 +1970,87 @@ | |
| 1967 | db_multi_exec( |
| 1968 | "DELETE FROM config " |
| 1969 | " WHERE name GLOB 'peer-*'" |
| 1970 | " OR name GLOB 'login-group-*';" |
| 1971 | ); |
| 1972 | } |
| 1973 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1821,20 +1821,20 @@ | |
| 1821 | ** |
| 1822 | ** If problems arise, leave an error message in *pzErrMsg. |
| 1823 | */ |
| 1824 | void login_group_join( |
| 1825 | const char *zRepo, /* Repository file in the login group */ |
| 1826 | int bPwRequired, /* True if the login,password is required */ |
| 1827 | const char *zLogin, /* Login name for the other repo */ |
| 1828 | const char *zPassword, /* Password to prove we are authorized to join */ |
| 1829 | const char *zNewName, /* Name of new login group if making a new one */ |
| 1830 | char **pzErrMsg /* Leave an error message here */ |
| 1831 | ){ |
| 1832 | Blob fullName; /* Blob for finding full pathnames */ |
| 1833 | sqlite3 *pOther; /* The other repository */ |
| 1834 | int rc; /* Return code from sqlite3 functions */ |
| 1835 | char *zOtherProjCode; /* Project code for pOther */ |
| 1836 | char *zSelfRepo; /* Name of our repository */ |
| 1837 | char *zSelfLabel; /* Project-name for our repository */ |
| 1838 | char *zSelfProjCode; /* Our project-code */ |
| 1839 | char *zSql; /* SQL to run on all peers */ |
| 1840 | const char *zSelf; /* The ATTACH name of our repository */ |
| @@ -1886,21 +1886,24 @@ | |
| 1886 | ** valid and has Setup permission. |
| 1887 | */ |
| 1888 | db_attach(zRepo, "other"); |
| 1889 | zOtherProjCode = db_text("x", "SELECT value FROM other.config" |
| 1890 | " WHERE name='project-code'"); |
| 1891 | if( bPwRequired ){ |
| 1892 | char *zPwHash; /* Password hash on pOther */ |
| 1893 | zPwHash = sha1_shared_secret(zPassword, zLogin, zOtherProjCode); |
| 1894 | if( !db_exists( |
| 1895 | "SELECT 1 FROM other.user" |
| 1896 | " WHERE login=%Q AND cap GLOB '*s*'" |
| 1897 | " AND (pw=%Q OR pw=%Q)", |
| 1898 | zLogin, zPassword, zPwHash) |
| 1899 | ){ |
| 1900 | db_detach("other"); |
| 1901 | *pzErrMsg = "The supplied username/password does not correspond to a" |
| 1902 | " user Setup permission on the other repository."; |
| 1903 | return; |
| 1904 | } |
| 1905 | } |
| 1906 | |
| 1907 | /* Create all the necessary CONFIG table entries on both the |
| 1908 | ** other repository and on our own repository. |
| 1909 | */ |
| @@ -1967,6 +1970,87 @@ | |
| 1970 | db_multi_exec( |
| 1971 | "DELETE FROM config " |
| 1972 | " WHERE name GLOB 'peer-*'" |
| 1973 | " OR name GLOB 'login-group-*';" |
| 1974 | ); |
| 1975 | } |
| 1976 | |
| 1977 | /* |
| 1978 | ** COMMAND: login-group |
| 1979 | ** |
| 1980 | ** Usage: %fossil login-group |
| 1981 | ** or: %fossil login-group join REPO [-name NAME] |
| 1982 | ** or: %fossil login-group leave |
| 1983 | ** |
| 1984 | ** With no arguments, this command shows the login-group to which the |
| 1985 | ** repository belongs. |
| 1986 | ** |
| 1987 | ** The "join" command adds this repository to login group to which REPO |
| 1988 | ** belongs, or creates a new login group between itself and REPO if REPO |
| 1989 | ** does not already belong to a login-group. When creating a new login- |
| 1990 | ** group, the name of the new group is determined by the "--name" option. |
| 1991 | ** |
| 1992 | ** The "leave" command takes the repository out of whatever login group |
| 1993 | ** it is currently a part of. |
| 1994 | ** |
| 1995 | ** About Login Groups: |
| 1996 | ** |
| 1997 | ** A login-group is a set of repositories that share user credentials. |
| 1998 | ** If a user is logged into one member of the group, then that user can |
| 1999 | ** access any other group member as long as they have an entry in the |
| 2000 | ** USER table of that member. If a user changes their password using |
| 2001 | ** web interface, their password is also automatically changed in every |
| 2002 | ** other member of the login group. |
| 2003 | */ |
| 2004 | void login_group_command(void){ |
| 2005 | const char *zLGName; |
| 2006 | const char *zCmd; |
| 2007 | int nCmd; |
| 2008 | Stmt q; |
| 2009 | db_find_and_open_repository(0,0); |
| 2010 | if( g.argc>2 ){ |
| 2011 | zCmd = g.argv[2]; |
| 2012 | nCmd = (int)strlen(zCmd); |
| 2013 | if( strncmp(zCmd,"join",nCmd)==0 && nCmd>=1 ){ |
| 2014 | const char *zNewName = find_option("name",0,1); |
| 2015 | const char *zOther; |
| 2016 | char *zErr = 0; |
| 2017 | verify_all_options(); |
| 2018 | if( g.argc!=4 ){ |
| 2019 | fossil_fatal("unknown extra arguments to \"login-group add\""); |
| 2020 | } |
| 2021 | zOther = g.argv[3]; |
| 2022 | login_group_join(zOther,0,0,0,zNewName,&zErr); |
| 2023 | if( zErr ){ |
| 2024 | fossil_fatal("%s", zErr); |
| 2025 | } |
| 2026 | }else if( strncmp(zCmd,"leave",nCmd)==0 && nCmd>=1 ){ |
| 2027 | verify_all_options(); |
| 2028 | if( g.argc!=3 ){ |
| 2029 | fossil_fatal("unknown extra arguments to \"login-group leave\""); |
| 2030 | } |
| 2031 | zLGName = login_group_name(); |
| 2032 | if( zLGName ){ |
| 2033 | char *zErr = 0; |
| 2034 | fossil_print("Leaving login-group \"%s\"\n", zLGName); |
| 2035 | login_group_leave(&zErr); |
| 2036 | return; |
| 2037 | } |
| 2038 | }else{ |
| 2039 | fossil_fatal("unknown command \"%s\" - should be \"add\" or \"leave\"", |
| 2040 | zCmd); |
| 2041 | } |
| 2042 | } |
| 2043 | /* Show the current login group information */ |
| 2044 | zLGName = login_group_name(); |
| 2045 | if( zLGName==0 ){ |
| 2046 | fossil_print("Not currently a part of any login-group\n"); |
| 2047 | return; |
| 2048 | } |
| 2049 | fossil_print("Now part of login-group \"%s\" with:\n", zLGName); |
| 2050 | db_prepare(&q, "SELECT value FROM config WHERE name LIKE 'peer-name-%%'"); |
| 2051 | while( db_step(&q)==SQLITE_ROW ){ |
| 2052 | fossil_print(" %s\n", db_column_text(&q,0)); |
| 2053 | } |
| 2054 | db_finalize(&q); |
| 2055 | |
| 2056 | } |
| 2057 |
+1
-1
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -558,11 +558,11 @@ | ||
| 558 | 558 | } |
| 559 | 559 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 560 | 560 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 561 | 561 | blob_reset(&fullName); |
| 562 | 562 | if( P("join")!=0 ){ |
| 563 | - login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg); | |
| 563 | + login_group_join(zRepo, 1, zLogin, zPw, zNewName, &zErrMsg); | |
| 564 | 564 | }else if( P("leave") ){ |
| 565 | 565 | login_group_leave(&zErrMsg); |
| 566 | 566 | } |
| 567 | 567 | style_header("Login Group Configuration"); |
| 568 | 568 | if( zErrMsg ){ |
| 569 | 569 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -558,11 +558,11 @@ | |
| 558 | } |
| 559 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 560 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 561 | blob_reset(&fullName); |
| 562 | if( P("join")!=0 ){ |
| 563 | login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg); |
| 564 | }else if( P("leave") ){ |
| 565 | login_group_leave(&zErrMsg); |
| 566 | } |
| 567 | style_header("Login Group Configuration"); |
| 568 | if( zErrMsg ){ |
| 569 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -558,11 +558,11 @@ | |
| 558 | } |
| 559 | file_canonical_name(g.zRepositoryName, &fullName, 0); |
| 560 | zSelfRepo = fossil_strdup(blob_str(&fullName)); |
| 561 | blob_reset(&fullName); |
| 562 | if( P("join")!=0 ){ |
| 563 | login_group_join(zRepo, 1, zLogin, zPw, zNewName, &zErrMsg); |
| 564 | }else if( P("leave") ){ |
| 565 | login_group_leave(&zErrMsg); |
| 566 | } |
| 567 | style_header("Login Group Configuration"); |
| 568 | if( zErrMsg ){ |
| 569 |