Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.88</version>
<version>5.6</version>
<relativePath />
</parent>
<artifactId>gitlab-oauth</artifactId>
Expand All @@ -13,13 +13,11 @@
<properties>
<revision>1.20</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.baseline>2.452</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.4</jenkins.version>
<jenkins.baseline>2.479</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
<spotbugs.effort>Max</spotbugs.effort>
<spotbugs.threshold>Low</spotbugs.threshold>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<name>GitLab Authentication plugin</name>
<description>A Jenkins authentication plugin that delegates to GitLab. We also implement an Authorization Strategy that users the acquired OAuth token to interact with the GitLab API to determine a users level of access to Jenkins.</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ of this software and associated documentation files (the "Software"), to deal

package org.jenkinsci.plugins;

import org.acegisecurity.AuthenticationException;
import org.springframework.security.core.AuthenticationException;

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.AbstractAuthenticationToken;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.gitlab4j.api.Constants.TokenType;
Expand All @@ -52,6 +49,9 @@
import org.gitlab4j.api.models.Group;
import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.User;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

/**
* @author mocleiri
Expand Down Expand Up @@ -93,237 +93,237 @@
private final List<GrantedAuthority> authorities = new ArrayList<>();

public GitLabAuthenticationToken(String accessToken, String gitlabServer, TokenType tokenType) throws GitLabApiException {
super(new GrantedAuthority[] {});
super(List.of());

this.accessToken = accessToken;
this.gitLabAPI = new GitLabApi(gitlabServer, tokenType, accessToken);

this.me = Objects.requireNonNull(gitLabAPI.getUserApi().getCurrentUser());

setAuthenticated(true);

this.userName = this.me.getUsername();
authorities.add(SecurityRealm.AUTHENTICATED_AUTHORITY);
authorities.add(SecurityRealm.AUTHENTICATED_AUTHORITY2);
Jenkins jenkins = Jenkins.getInstanceOrNull();
if (jenkins != null && jenkins.getSecurityRealm() instanceof GitLabSecurityRealm) {

myRealm = (GitLabSecurityRealm) jenkins.getSecurityRealm();

// Search for scopes that allow fetching team membership. This is
// documented online.
// https://developer.gitlab.com/v3/orgs/#list-your-organizations
// https://developer.gitlab.com/v3/orgs/teams/#list-user-teams
List<Group> myTeams = gitLabAPI.getGroupApi().getGroups();
for (Group group : myTeams) {
LOGGER.log(Level.FINE, "Fetch teams for user " + userName + " in organization " + group.getName());

GitLabOAuthGroupDetails gitLabOAuthGroupDetails = new GitLabOAuthGroupDetails(group);

authorities.add(gitLabOAuthGroupDetails.getAuth());
}
}
}

/**
* Necessary for testing
*/
public static void clearCaches() {
userOrganizationCache.invalidateAll();
repositoryCollaboratorsCache.invalidateAll();
repositoriesByUserCache.invalidateAll();
groupRepositoriesCache.invalidateAll();
}

/**
* Gets the OAuth access token, so that it can be persisted and used
* elsewhere.
*/
public String getAccessToken() {
return accessToken;
}

public GitLabApi getGitLabAPI() {
return gitLabAPI;
}

@Override
public GrantedAuthority[] getAuthorities() {
return authorities.toArray(new GrantedAuthority[0]);
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}

@Override
public Object getCredentials() {
return ""; // do not expose the credential
}

/**
* Returns the login name in GitLab.
*/
@Override
public String getPrincipal() {
return this.userName;
}

/**
* Returns the GHMyself object from this instance.
*/
public User getMyself() {
return me;
}

/**
* For some reason I can't get the gitlab api to tell me for the current
* user the groups to which he belongs.
*
* So this is a slightly larger consideration. If the authenticated user is
* part of any team within the organization then they have permission.
*
* It caches user organizations for 24 hours for faster web navigation.
*
* @param candidateName
* @param organization
* @return whether given candidate belongs to a given organization
*/
public boolean hasOrganizationPermission(String candidateName, String organization) {
Set<String> v = userOrganizationCache.get(candidateName, unused -> {
try {
List<Group> groups = gitLabAPI.getGroupApi().getGroups();
Set<String> groupsNames = new HashSet<>();
for (Group group : groups) {
groupsNames.add(group.getName());
}
return groupsNames;
} catch (GitLabApiException e) {
throw new RuntimeException("authorization failed for user = " + candidateName, e);
}
});

return v != null && v.contains(organization);
}

public boolean hasRepositoryPermission(final String repositoryName) {
return myRepositories().contains(repositoryName);
}

public Set<String> myRepositories() {
Set<String> myRepositories = repositoriesByUserCache.get(getName(), unused -> {
try {
// Get user's projects
List<Project> userRepositoryList = gitLabAPI.getProjectApi().getProjects();
Set<String> repositoryNames = Collections.emptySet();
if (userRepositoryList != null) {
repositoryNames = listToNames(userRepositoryList);
}
// Disable for security reason.
// If enabled, even group guest can manage all group jobs.
// // Get user's groups
// List<Group> userGroups = gitLabAPI.getGroups();
// if (userGroups != null) {
// for (Group group : userGroups) {
// List<Project> groupProjects = getGroupProjects(group);
// if (groupProjects != null) {
// Set<String> groupProjectNames = listToNames(groupProjects);
// repositoryNames.addAll(groupProjectNames);
// }
// }
// }
return repositoryNames;
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
});

return myRepositories;
}

public Set<String> listToNames(Collection<Project> repositories) {
Set<String> names = new HashSet<>();
for (Project repository : repositories) {
// String ownerName = repository.getOwner().getUsername();
// String repoName = repository.getName();
// names.add(ownerName + "/" + repoName);
// Do not use owner! Project belongs to group does not have owner!
names.add(repository.getPathWithNamespace());
}
return names;
}

public boolean isPublicRepository(final String repositoryName) {
Boolean isPublic = publicRepositoryCache.get(repositoryName, unused -> {
Project repository = loadRepository(repositoryName);
if (repository == null) {
// We don't have access so it must not be public (it
// could be non-existant)
return Boolean.FALSE;
} else {
return Boolean.TRUE.equals(repository.getPublic());
}
});

return isPublic != null && isPublic;
}

private static final Logger LOGGER = Logger.getLogger(GitLabAuthenticationToken.class.getName());

public User loadUser(String username) {
try {
if (gitLabAPI != null && isAuthenticated()) {
List<User> users = gitLabAPI.getUserApi().findUsers(username);
if (CollectionUtils.isNotEmpty(users)) {
return users.get(0); // FIXME : find best solution
}
}
} catch (GitLabApiException e) {
LOGGER.log(Level.FINEST, e.getMessage(), e);
}
return null;
}

public Group loadOrganization(String organization) {
if (StringUtils.isEmpty(organization)) return null;
try {
if (gitLabAPI != null && isAuthenticated()) {
List<Group> gitLabGroups = gitLabAPI.getGroupApi().getGroups();
if (!gitLabGroups.isEmpty()) {
return gitLabGroups.stream().filter(group -> group.getName().equalsIgnoreCase(organization)).findFirst().orElse(null);
}
}
} catch (GitLabApiException e) {
LOGGER.log(Level.FINEST, e.getMessage(), e);
}
return null;
}

public Project loadRepository(String repositoryName) {
try {
if (gitLabAPI != null && isAuthenticated()) {
return gitLabAPI.getProjectApi().getProject(repositoryName);
}
} catch (GitLabApiException e) {
LOGGER.log(Level.WARNING,
"Looks like a bad GitLab URL OR the Jenkins user does not have access to the repository{0}",
repositoryName);
}
return null;
}

/**
* @since 0.21
*/
public GitLabOAuthUserDetails getUserDetails(String username) {
User user = loadUser(username);
if (user != null) {
// FIXME to implement
List<GrantedAuthority> groups = new ArrayList<>();
try {
List<Group> gitLabGroups = gitLabAPI.getGroupApi().getGroups();
for (Group gitlabGroup : gitLabGroups) {
groups.add(new GrantedAuthorityImpl(gitlabGroup.getName()));
groups.add(new SimpleGrantedAuthority(gitlabGroup.getName()));
}
} catch (GitLabApiException e) {
LOGGER.log(Level.FINE, e.getMessage(), e);
}
return new GitLabOAuthUserDetails(user, groups.toArray(new GrantedAuthority[0]));
return new GitLabOAuthUserDetails(user, groups);

Check warning on line 326 in src/main/java/org/jenkinsci/plugins/GitLabAuthenticationToken.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 96-326 are not covered by tests
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
package org.jenkinsci.plugins;

import hudson.security.GroupDetails;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.gitlab4j.api.models.Group;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

/**
* Represent a group from GitLab as a group in Jenkins terms.
Expand Down Expand Up @@ -60,6 +60,6 @@
}

public GrantedAuthority getAuth() {
return new GrantedAuthorityImpl(getName());
return new SimpleGrantedAuthority(getName());

Check warning on line 63 in src/main/java/org/jenkinsci/plugins/GitLabOAuthGroupDetails.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 63 is not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.jenkinsci.plugins;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.userdetails.User;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

/**
* @author Mike
Expand All @@ -11,7 +12,7 @@ public class GitLabOAuthUserDetails extends User {

private static final long serialVersionUID = 1709511212188366292L;

public GitLabOAuthUserDetails(org.gitlab4j.api.models.User user, GrantedAuthority[] authorities) {
public GitLabOAuthUserDetails(org.gitlab4j.api.models.User user, Collection<? extends GrantedAuthority> authorities) {
super(user.getUsername(), "", true, true, true, true, authorities);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
import java.util.List;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
import org.acegisecurity.Authentication;
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerRequest2;
import org.springframework.security.core.Authentication;

/**
* @author Mike
Expand All @@ -70,11 +70,11 @@
/*
* (non-Javadoc)
*
* @see hudson.security.ACL#hasPermission(org.acegisecurity.Authentication,
* @see hudson.security.ACL#hasPermission(org.springframework.security.core.Authentication,
* hudson.security.Permission)
*/
@Override
public boolean hasPermission(Authentication a, Permission permission) {
public boolean hasPermission2(Authentication a, Permission permission) {
if (a != null && a instanceof GitLabAuthenticationToken) {
if (!a.isAuthenticated()) {
return false;
Expand Down Expand Up @@ -154,76 +154,76 @@
} else {
String authenticatedUserName = a.getName();

if (authenticatedUserName.equals(SYSTEM.getPrincipal())) {
if (authenticatedUserName.equals(SYSTEM2.getPrincipal())) {
// give system user full access
log.finest("Granting Full rights to SYSTEM user.");
return true;
}
if (authenticatedUserName.equals("anonymous")) {
if (checkJobStatusPermission(permission) && allowAnonymousJobStatusPermission) {
return true;
}
if (checkReadPermission(permission)) {
if (allowAnonymousReadPermission) {
return true;
}
if (allowGitlabWebHookPermission &&
(currentUriPathStartsWith("/project/") ||
currentUriPathEquals("gitlab-webhook") ||
currentUriPathEquals("gitlab-webhook/"))) {
log.finest("Granting READ access for gitlab-webhook url: " + requestURI());
return true;
}
if (allowCcTrayPermission && currentUriPathEquals("cc.xml")) {
log.finest("Granting READ access for cctray url: " + requestURI());
return true;
}
log.finer("Denying anonymous READ permission to url: " + requestURI());
}

if (testBuildPermission(permission)) {
if (allowGitlabWebHookPermission &&
(currentUriPathStartsWith("/project/") ||
currentUriPathEquals("gitlab-webhook") ||
currentUriPathEquals("gitlab-webhook/"))) {
log.finest("Granting BUILD access for gitlab-webhook url: " + requestURI());
return true;
}
}
return false;
}

if (adminUserNameList.contains(authenticatedUserName)) {
// if they are an admin then they have all permissions
log.finest("Granting Admin rights to user " + a.getName());
return true;
}

// else:
// deny request
//
return false;
}
}

private boolean currentUriPathStartsWith(String specificPath) {
String requestUri = requestURI();
return requestUri != null && requestUri.startsWith(specificPath);
}

private boolean currentUriPathEquals(String specificPath) {
String requestUri = requestURI();
Jenkins jenkins = Jenkins.getInstanceOrNull();
if (jenkins != null && requestUri != null) {
String basePath = URI.create(jenkins.getRootUrl()).getPath();
return URI.create(requestUri).getPath().equals(basePath + specificPath);
} else {
return false;
}
}

private String requestURI() {
StaplerRequest currentRequest = Stapler.getCurrentRequest();
StaplerRequest2 currentRequest = Stapler.getCurrentRequest2();

Check warning on line 226 in src/main/java/org/jenkinsci/plugins/GitLabRequireOrganizationMembershipACL.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 157-226 are not covered by tests
return (currentRequest == null) ? null : currentRequest.getOriginalRequestURI();
}

Expand Down
53 changes: 25 additions & 28 deletions src/main/java/org/jenkinsci/plugins/GitLabSecurityRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@
import hudson.model.User;
import hudson.security.GroupDetails;
import hudson.security.SecurityRealm;
import hudson.security.UserMayOrMayNotExistException;
import hudson.security.UserMayOrMayNotExistException2;
import hudson.tasks.Mailer;
import hudson.util.Secret;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
Expand All @@ -55,18 +56,8 @@
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.servlet.http.HttpSession;
import jenkins.model.Jenkins;
import jenkins.security.SecurityListener;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException;
import org.acegisecurity.AuthenticationManager;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.http.HttpEntity;
Expand All @@ -91,9 +82,17 @@
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.HttpResponses;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
import org.kohsuke.stapler.StaplerRequest2;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
*
Expand All @@ -103,7 +102,7 @@
* This is based on the GitLabSecurityRealm from the gitlab-auth-plugin written
* by Alex Ackerman.
*/
public class GitLabSecurityRealm extends SecurityRealm implements UserDetailsService {
public class GitLabSecurityRealm extends SecurityRealm {
private String gitlabWebUri;
private String gitlabApiUri;
private String clientID;
Expand Down Expand Up @@ -266,7 +265,7 @@

// "from" is coming from SecurityRealm/loginLink.jelly
public HttpResponse doCommenceLogin(
StaplerRequest request, @QueryParameter String from, @Header("Referer") final String referer)
StaplerRequest2 request, @QueryParameter String from, @Header("Referer") final String referer)
throws IOException {
// 2. Requesting authorization :
// http://doc.gitlab.com/ce/api/oauth2.html
Expand Down Expand Up @@ -298,7 +297,7 @@
gitlabWebUri + "/oauth/authorize?" + URLEncodedUtils.format(parameters, StandardCharsets.UTF_8));
}

private String buildRedirectUrl(StaplerRequest request) throws MalformedURLException {
private String buildRedirectUrl(StaplerRequest2 request) throws MalformedURLException {
URL currentUrl = new URL(Jenkins.get().getRootUrl());

URL redirect_uri = new URL(
Expand All @@ -313,7 +312,7 @@
* This is where the user comes back to at the end of the OpenID redirect
* ping-pong.
*/
public HttpResponse doFinishLogin(StaplerRequest request) throws IOException {
public HttpResponse doFinishLogin(StaplerRequest2 request) throws IOException {
String code = request.getParameter("code");
String state = request.getParameter(STATE_ATTRIBUTE);
String expectedState = (String) request.getSession().getAttribute(STATE_ATTRIBUTE);
Expand Down Expand Up @@ -394,185 +393,184 @@
new Mailer.UserProperty(auth.getMyself().getEmail()));
}
}
SecurityListener.fireAuthenticated(new GitLabOAuthUserDetails(self, auth.getAuthorities()));
SecurityListener.fireAuthenticated2(new GitLabOAuthUserDetails(self, auth.getAuthorities()));
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
} else {
Log.info("GitLab did not return an access token.");
}

if (StringUtils.isNotBlank(referer)) {
return HttpResponses.redirectTo(referer);
}
return HttpResponses.redirectToContextRoot();
}

/**
* Returns the proxy to be used when connecting to the given URI.
*/
private HttpHost getProxy(HttpUriRequest method) {
Jenkins jenkins = Jenkins.get();
ProxyConfiguration proxy = jenkins.proxy;
if (proxy == null) {
return null; // defensive check
}

Proxy p = proxy.createProxy(method.getURI().getHost());
switch (p.type()) {
case DIRECT:
return null; // no proxy
case HTTP:
InetSocketAddress sa = (InetSocketAddress) p.address();
return new HttpHost(sa.getHostName(), sa.getPort());
case SOCKS:
default:
return null; // not supported yet
}
}

private String extractToken(String content) {

try {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonTree = mapper.readTree(content);
JsonNode node = jsonTree.get("access_token");
if (node != null) {
return node.asText();
}
} catch (IOException e) {
Log.error(e.getMessage(), e);
}
return null;
}

/**
* To store the state parameter in the user's session.
*/
private static final String STATE_ATTRIBUTE = "state";

/*
* (non-Javadoc)
*
* @see hudson.security.SecurityRealm#allowsSignup()
*/
@Override
public boolean allowsSignup() {
return false;
}

@Override
public SecurityComponents createSecurityComponents() {
return new SecurityComponents(
new AuthenticationManager() {

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication instanceof GitLabAuthenticationToken) {
return authentication;
}
if (authentication instanceof UsernamePasswordAuthenticationToken) {
try {
UsernamePasswordAuthenticationToken token =
(UsernamePasswordAuthenticationToken) authentication;
GitLabAuthenticationToken gitlab = new GitLabAuthenticationToken(
token.getCredentials().toString(), getGitlabApiUri(), TokenType.PRIVATE);
SecurityContextHolder.getContext().setAuthentication(gitlab);
return gitlab;
} catch (GitLabApiException e) {
throw new RuntimeException(e);
}
}
throw new BadCredentialsException("Unexpected authentication type: " + authentication);
}
},
new UserDetailsService() {
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
return GitLabSecurityRealm.this.loadUserByUsername(username);
throws UsernameNotFoundException {
return GitLabSecurityRealm.this.loadUserByUsername2(username);
}
});
}

@Override
public String getLoginUrl() {
return "securityRealm/commenceLogin";
}

@Override
protected String getPostLogOutUrl(StaplerRequest req, Authentication auth) {
protected String getPostLogOutUrl2(StaplerRequest2 req, Authentication auth) {
// if we just redirect to the root and anonymous does not have Overall read then we will start a login all over
// again.
// we are actually anonymous here as the security context has been cleared
Jenkins jenkins = Jenkins.get();
if (jenkins.hasPermission(Jenkins.READ)) {
// TODO until JEP-227 is merged and core requirement is updated, this will prevent stackoverflow
return req.getContextPath() + "/";
}
return req.getContextPath() + "/" + GitLabLogoutAction.POST_LOGOUT_URL;
}

@Extension
public static final class DescriptorImpl extends Descriptor<SecurityRealm> {

@Override
public String getHelpFile() {
return "/plugin/gitlab-oauth/help/help-security-realm.html";
}

@Override
public String getDisplayName() {
return "GitLab Authentication Plugin";
}

public DescriptorImpl() {
// default constructor
}

public DescriptorImpl(Class<? extends SecurityRealm> clazz) {
super(clazz);
}
}

// Overridden for better type safety.
// If your plugin doesn't really define any property on Descriptor,
// you don't have to do this.
@Override
public DescriptorImpl getDescriptor() {
return (DescriptorImpl) super.getDescriptor();
}

/**
* @param username
* @throws UsernameNotFoundException
* @throws DataAccessException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
public UserDetails loadUserByUsername2(String username) throws UsernameNotFoundException {
GitLabAuthenticationToken authToken;
if (SecurityContextHolder.getContext().getAuthentication() instanceof GitLabAuthenticationToken) {
authToken = (GitLabAuthenticationToken)
SecurityContextHolder.getContext().getAuthentication();
} else {
throw new UserMayOrMayNotExistException("Could not get auth token.");
throw new UserMayOrMayNotExistException2("Could not get auth token.");
}

try {
GitLabOAuthUserDetails userDetails = authToken.getUserDetails(username);
if (userDetails == null) {
throw new UsernameNotFoundException("Unknown user: " + username);
}

// Check the username is not an homonym of an organization
Group ghOrg = authToken.loadOrganization(username);
if (ghOrg != null) {
throw new UsernameNotFoundException("user(" + username + ") is also an organization");
}

return userDetails;
} catch (Error e) {
throw new DataRetrievalFailureException("loadUserByUsername (username=" + username + ")", e);
throw new AuthenticationServiceException("loadUserByUsername (username=" + username + ")", e);

Check warning on line 573 in src/main/java/org/jenkinsci/plugins/GitLabSecurityRealm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 396-573 are not covered by tests
}
}

Expand Down Expand Up @@ -604,10 +602,9 @@
/**
* @param groupName
* @throws UsernameNotFoundException
* @throws DataAccessException
*/
@Override
public GroupDetails loadGroupByGroupname(String groupName) throws UsernameNotFoundException, DataAccessException {
public GroupDetails loadGroupByGroupname2(String groupName, boolean fetchMembers) throws UsernameNotFoundException {

GitLabAuthenticationToken authToken =
(GitLabAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Expand Down
Loading