package com.perforce.hive.connection; import com.perforce.hive.ErrorModel; import com.perforce.hive.navigation.NavBar; import com.perforce.p4java.admin.IProtectionEntry; import com.perforce.p4java.exception.P4JavaException; import com.perforce.p4java.option.server.GetProtectionEntriesOptions; import com.perforce.p4java.server.IOptionsServer; import com.perforce.p4java.server.callback.ICommandCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import spark.ModelAndView; import spark.Request; import spark.Response; import java.util.Base64; import java.util.List; import java.util.Map; public class ConnectionSession extends ErrorModel { private static Logger logger = LoggerFactory.getLogger(ConnectionSession.class); public static String TICKET = "ticket"; public static String USER = "username"; static String PASS = "password"; public static boolean basicAuth(Request request, Response response) { String authHeader = request.raw().getHeader("Authorization"); // exit early if not Basic Auth if (authHeader == null || !authHeader.startsWith("Basic ")) { return false; } String baseHeader = authHeader.substring("basic ".length()); byte[] bytes = Base64.getDecoder().decode(baseHeader); String decode = new String(bytes); String bits[] = decode.split(":"); if (bits.length != 2) { logger.info("[login] Basic Auth: no user or pass."); return false; } String user = bits[0]; String pass = bits[1]; logger.info("[login] Basic Auth: " + user); String ticket; try { ticket = login(user, pass); } catch (P4JavaException e) { return false; } request.session().attribute(ConnectionSession.USER, user); request.session().attribute(ConnectionSession.TICKET, ticket); return true; } public static IOptionsServer get(Request request, Response response) throws P4JavaException { // use Perforce ticket from session String user = request.session().attribute(ConnectionSession.USER); String ticket = request.session().attribute(ConnectionSession.TICKET); try { if (user != null) { logger.info("[login] Session: " + user); IOptionsServer p4 = getP4(user, ticket); return p4; } } catch (P4JavaException e) { // wipe out cookie and session logout(request, response); } // use the 'anonymous' account to view or proxy files user = ConnectionConfig.get().getAnonymousUser(); ticket = ConnectionConfig.get().getAnonymousTicket(); try { logger.info("[login] Anonymous"); IOptionsServer p4 = getP4(user, ticket); return p4; } catch (P4JavaException e) { // wipe out cookie and session logout(request, response); throw e; } } public static AuthLevel getAuth(Request request) { String user = request.session().attribute(ConnectionSession.USER); String ticket = request.session().attribute(ConnectionSession.TICKET); // if no user fall back to Anonymous and return AuthLevel.ANONYMOUS if (user == null) { return AuthLevel.ANONYMOUS; } try { IOptionsServer p4 = getP4(user, ticket); GetProtectionEntriesOptions opts = new GetProtectionEntriesOptions(); List<IProtectionEntry> protect = p4.getProtectionEntries(null, opts); for (IProtectionEntry p : protect) { if ("super".equals(p.getMode())) { return AuthLevel.SUPER; } } return AuthLevel.VALID; } catch (P4JavaException e) { return AuthLevel.NONE; } } public static IOptionsServer getP4(String user, String ticket) throws P4JavaException { String uri = ConnectionConfig.get().toUri(); IOptionsServer p4 = ConnectionFactory.getConnection(uri); p4.connect(); p4.setUserName(user); p4.setAuthTicket(ticket); // Register logging callback ICommandCallback logging = new ConnectionLogging(p4); p4.registerCallback(logging); // verify connection try { isLogin(p4); } catch (P4JavaException e) { throw e; } return p4; } public static String login(String user, String pass) throws P4JavaException { String uri = ConnectionConfig.get().toUri(); IOptionsServer p4 = ConnectionFactory.getConnection(uri); // fail if server is down. p4.connect(); // login and use Perforce ticket for session p4.setUserName(user); // fetch ticket String ticket = null; p4.login(pass); // check for null ticket ticket = p4.getAuthTicket(); if (ticket == null) { throw new P4JavaException("Ticket value is null."); } return ticket; } public static ModelAndView login(Request request, Response response) { Map<String, Object> model; model = NavBar.attributes("cover", request); String user = request.queryParams(USER); String pass = request.queryParams(PASS); String ticket = null; try { ticket = login(user, pass); } catch (Exception e) { return error(e); } // store ticket in session request.session().attribute(USER, user); request.session().attribute(TICKET, ticket); // save cookie String store = request.queryParams("store"); if (store != null) { response.cookie(USER, user); response.cookie(TICKET, ticket); } response.redirect("/"); return new ModelAndView(model, "page-cover.html"); } public static void logout(Request request, Response response) { request.session().removeAttribute(USER); request.session().removeAttribute(TICKET); response.removeCookie(USER); response.removeCookie(TICKET); } public static void cookie(Request request, Response response) { String user = request.cookie(USER); String ticket = request.cookie(TICKET); // exit early if no cookie if (user == null) { return; } logger.info("[login] Cookie: " + user); try { getP4(user, ticket); } catch (P4JavaException e) { logout(request, response); return; } // store ticket in session request.session().attribute(USER, user); request.session().attribute(TICKET, ticket); } private static void isLogin(IOptionsServer p4) throws P4JavaException { String status = p4.getLoginStatus(); if (status.contains("not necessary")) { return; } if (status.contains("ticket expires in")) { return; } // If there is a broker or something else that swallows the message if (status.isEmpty()) { return; } throw new P4JavaException(status); } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#11 | 25846 | Paul Allen | Workaround for 19.1 p4java - change in output for protects -m | ||
#10 | 18897 | Paul Allen |
Docker push support. Detects existing blobs and uploads new. Removed multi-docker repositories while fixing API. Test command: 'docker push docker.local.hive:4567/ubuntu' |
||
#9 | 18280 | Paul Allen |
Tests framework for Hive. Starts up an RSH Perforce server and overrides the default connection configuration. Load PF4J plugins as required. |
||
#8 | 18161 | Paul Allen |
Direct Deploy for the command line. For example: mvn deploy:deploy-file -DgroupId=com.test -DartifactId=project -Dversion=1.0.0 -DgeneratePom=true -Dpackaging=jar -DrepositoryId=hive -Durl=http://localhost:4567/view/maven -Dfile=test.jar Auth set in ~/.m2/settings.xml <server> <id>hive</id> <username>admin</username> <password>Password</password> </server> or using Curl: curl -v -u admin:Password --upload-file test.jar http://localhost:4567/view/depot/com/test/test.jar |
||
#7 | 18032 | Paul Allen | With login changes consider user 'anonymous' for UX as not logged in. | ||
#6 | 18031 | Paul Allen | Missing Files ClientHelper and HiveProxyException, with login improvment. | ||
#5 | 17295 | Paul Allen |
Auth support for Anonymous and Proxy users. - Anonymous needs 'read' on all Hive depots. - Proxy needs 'write' on all Group/Proxy Hive depots. - Logging improvments Workaround for 'p4 files' needing a client. |
||
#4 | 16608 | Paul Allen | Obliterate option on files/dirs. | ||
#3 | 16598 | Paul Allen | Update login field names to 'username' and 'password'. | ||
#2 | 16414 | Paul Allen |
Split User roles. Anonymous user for general browsing and Proxy user for serving content and submitting cached content. |
||
#1 | 16001 | Paul Allen | Renamed package to com.perforce.hive | ||
//guest/perforce_software/hive/main/core/src/main/java/com/perforce/spark/connection/ConnectionSession.java | |||||
#1 | 15998 | Paul Allen |
Refactor for plugin design. Moving main code to 'core'. |
||
//guest/perforce_software/hive/main/src/main/java/com/perforce/spark/connection/ConnectionSession.java | |||||
#3 | 15960 | Paul Allen |
User restriction for browse/search/deploy. When user is not logged in default anonymous users is used and only browse + search is available. Normal Perforce protections apply to browse/search visability. If user has 'super' the config menu is available. |
||
#2 | 15925 | Matt Attaway | Incremental pull of Hive | ||
#1 | 15923 | Matt Attaway | Next incremental pull of PAM (Java people love to refactor) | ||
//guest/paul_allen/p4am/src/main/java/com/perforce/spark/connection/ConnectionSession.java | |||||
#1 | 14228 | Paul Allen |
Moved View over to the new model. Retactor connection to package. |
||
//guest/paul_allen/p4am/src/main/java/com/perforce/spark/ConnectionSession.java | |||||
#9 | 14181 | Paul Allen | Lots of updates and refactoring. | ||
#8 | 14017 | Paul Allen | Proxy caching to Perforce and SLF4J logging. | ||
#7 | 14013 | Paul Allen | Basic proxy | ||
#6 | 13869 | Paul Allen |
- Fix logout when testing cookie. - Refactor ftl->html - Add local bootstrap |
||
#5 | 13863 | Paul Allen | Minor fix to session vs cookie for login check. | ||
#4 | 13798 | Paul Allen | Basic file upload and login/logout cookie tidyup | ||
#3 | 13746 | Paul Allen | Basic File/Dir browsing and Cookie management. | ||
#2 | 13728 | Paul Allen | Error support | ||
#1 | 13722 | Paul Allen | Login UX |