1   /*
2    * Copyright 2018 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package com.linecorp.centraldogma.server.auth;
17  
18  import static com.linecorp.centraldogma.internal.api.v1.HttpApiV1Constants.API_V0_PATH_PREFIX;
19  import static com.linecorp.centraldogma.internal.api.v1.HttpApiV1Constants.API_V1_PATH_PREFIX;
20  
21  import java.util.Set;
22  
23  import javax.annotation.Nullable;
24  
25  import com.google.common.collect.ImmutableList;
26  import com.google.common.collect.ImmutableSet;
27  
28  import com.linecorp.armeria.common.HttpHeaderNames;
29  import com.linecorp.armeria.common.HttpResponse;
30  import com.linecorp.armeria.common.HttpStatus;
31  import com.linecorp.armeria.common.ResponseHeaders;
32  import com.linecorp.armeria.server.HttpService;
33  import com.linecorp.armeria.server.HttpServiceWithRoutes;
34  import com.linecorp.armeria.server.Route;
35  import com.linecorp.armeria.server.Service;
36  
37  /**
38   * An interface which configures the authentication layer for the Central Dogma server.
39   */
40  public interface AuthProvider {
41      /**
42       * A login page path for the web console. If a user, who has not logged into the web console yet,
43       * opens the web console, the web browser would bring the user to the login page.
44       */
45      String LOGIN_PATH = "/link/auth/login";
46  
47      /**
48       * A logout page path for the web console. If a user clicks the logout button on the navigation bar,
49       * the web browser would bring the user to the logout page.
50       */
51      String LOGOUT_PATH = "/link/auth/logout";
52  
53      /**
54       * A base path of the built-in web app.
55       */
56      String BUILTIN_WEB_BASE_PATH = "/web/auth";
57  
58      /**
59       * A path which provides a built-in HTML login form to a user.
60       */
61      String BUILTIN_WEB_LOGIN_PATH = BUILTIN_WEB_BASE_PATH + "/login";
62  
63      /**
64       * A path which provides a built-in HTML logout page to a user.
65       */
66      String BUILTIN_WEB_LOGOUT_PATH = BUILTIN_WEB_BASE_PATH + "/logout";
67  
68      /**
69       * A set of {@link Route}s which handles a login request. It is necessary only if
70       * an authentication protocol requires a login feature provided by the server.
71       */
72      Set<Route> LOGIN_API_ROUTES =
73              ImmutableSet.of(Route.builder().exact(API_V0_PATH_PREFIX + "authenticate").build(),
74                              Route.builder().exact(API_V1_PATH_PREFIX + "login").build());
75  
76      /**
77       * A set of {@link Route}s which handles a logout request. It is necessary only if
78       * an authentication protocol requires a logout feature provided by the server.
79       */
80      Set<Route> LOGOUT_API_ROUTES =
81              ImmutableSet.of(Route.builder().exact(API_V0_PATH_PREFIX + "logout").build(),
82                              Route.builder().exact(API_V1_PATH_PREFIX + "logout").build());
83  
84      /**
85       * Returns a {@link Service} which handles a login request from a web browser. By default,
86       * the browser would bring a user to the built-in web login page served on {@value BUILTIN_WEB_LOGIN_PATH}.
87       */
88      default HttpService webLoginService() {
89          // Redirect to the default page: /link/auth/login -> /web/auth/login
90          return (ctx, req) -> HttpResponse.of(
91                  ResponseHeaders.of(HttpStatus.MOVED_PERMANENTLY, HttpHeaderNames.LOCATION,
92                                     BUILTIN_WEB_LOGIN_PATH));
93      }
94  
95      /**
96       * Returns a {@link Service} which handles a logout request from a web browser. By default,
97       * the browser would bring a user to the built-in web logout page served on
98       * {@value BUILTIN_WEB_LOGOUT_PATH}.
99       */
100     default HttpService webLogoutService() {
101         // Redirect to the default page: /link/auth/logout -> /web/auth/logout
102         return (ctx, req) -> HttpResponse.of(
103                 ResponseHeaders.of(HttpStatus.MOVED_PERMANENTLY, HttpHeaderNames.LOCATION,
104                                    BUILTIN_WEB_LOGOUT_PATH));
105     }
106 
107     /**
108      * Returns a {@link Service} which handles a login request sent from the built-in web login page or
109      * somewhere implemented by an {@link AuthProvider}. This service would be added to the server
110      * with {@link #LOGIN_API_ROUTES} only if it is provided.
111      */
112     @Nullable
113     default HttpService loginApiService() {
114         return null;
115     }
116 
117     /**
118      * Returns a {@link Service} which handles a logout request sent from the built-in web logout page or
119      * somewhere implemented by an {@link AuthProvider}. This service would be added to the server
120      * with {@link #LOGOUT_API_ROUTES}. If it is not provided, a default service would be added
121      * because the web console provides a logout button on the navigation bar by default.
122      */
123     @Nullable
124     default HttpService logoutApiService() {
125         return null;
126     }
127 
128     /**
129      * Returns additional {@link Service}s which are required for working this {@link AuthProvider}
130      * well.
131      */
132     default Iterable<HttpServiceWithRoutes> moreServices() {
133         return ImmutableList.of();
134     }
135 }